DevKim

[์Šคํ”„๋ง with AWS] CRU ๊ธฐ๋Šฅ - RestTemplate์œผ๋กœ API ํ…Œ์ŠคํŠธ ๋ณธ๋ฌธ

Spring Boot

[์Šคํ”„๋ง with AWS] CRU ๊ธฐ๋Šฅ - RestTemplate์œผ๋กœ API ํ…Œ์ŠคํŠธ

on_doing 2021. 7. 10. 14:56
728x90

๐Ÿƒ CH.03 ๐Ÿƒ

3์žฅ๋ถ€ํ„ฐ๋Š” ํ•˜๋‚˜์˜ ๊ฒŒ์‹œํŒ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ณ ,

7์žฅ์—์„œ 10์žฅ๊นŒ์ง€๋Š” ์ด ์„œ๋น„์Šค๋ฅผ AWS ๋ฌด์ค‘๋‹จ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ์ง„ํ–‰ํ•œ๋‹ค.


๐Ÿ“Œ Role #1

๊ธฐ๋ณธ์ ์œผ๋กœ Builder ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

๐Ÿ“Œ Role #2

Setter๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , 

๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ฑ„์šฐ๊ณ ,

๊ฐ’ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—” ๋ช…ํ™•ํ•˜๊ฒŒ ๊ทธ ๋ชฉ์ ๊ณผ ์˜๋„๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Posts {

    //id,title.content,author ์ƒ๋žต
    ...
    
    @Builder
    public Posts(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }
}

 

๐Ÿ“Œ ์ƒ์„ฑ์ž ๋Œ€์‹  ๋นŒ๋” ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š”,

์–ด๋Š ํ•„๋“œ์— ์–ด๋–ค ๊ฐ’์„ ์ฑ„์›Œ์•ผํ• ์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Example.builder()
	.a(a)
	.b(b)
	.build();

 

JpaRepository๋„ ์ƒ์„ฑํ•ด์ฃผ์—ˆ๋Š”๋ฐ,

์ด๋•Œ Entity ํด๋ž˜์Šค๋Š” ๊ธฐ๋ณธ Repository์™€ ํ•จ๊ป˜ ์œ„์น˜ํ•ด์•ผํ•œ๋‹ค๋Š” ์ ์ด ์ƒˆ๋กœ์› ๋‹ค.

์ด๋•Œ๊นŒ์ง„ repository๋งŒ ํ•œ ๊ณณ์— ๋ชจ์•„๋’€์—ˆ๋Š”๋ฐ, ๋‚˜์ค‘์— ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ ธ์„œ ๋„๋ฉ”์ธ๋ณ„๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์ƒํ™ฉ์ด ์˜จ๋‹ค๋ฉด ํ•จ๊ป˜ ์›€์ง์—ฌ์•ผํ•˜๋ฏ€๋กœ ๊ฐ™์ด ๋„๋ฉ”์ธ ํŒจํ‚ค์ง€์—์„œ ๊ด€๋ฆฌํ•œ๋‹ค๊ณ ํ•œ๋‹ค.

 

๐Ÿ“Œ JPA ๊ธฐ๋ณธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

@RunWith(SpringRunner.class)
@SpringBootTest
public class PostsRepositoryTest {

    @Autowired
    PostsRepository postsRepository;

    @After
    public void clenup()
    {
        postsRepository.deleteAll();
    }

    @Test
    public void ๊ฒŒ์‹œ๊ธ€์ €์žฅ_๋ถˆ๋Ÿฌ์˜ค๊ธฐ() throws Exception{
        //given
        String title="๊ฒŒ์‹œ๊ธ€ ์ œ๋ชฉ";
        String content="๊ฒŒ์‹œ๊ธ€ ๋ณธ๋ฌธ";

        postsRepository.save(Posts.builder()
                .title(title)
                .content(content)
                .author("abc@gmail.com")
                .build());

        //when
        List<Posts> postsList = postsRepository.findAll();

        //then
        Posts posts = postsList.get(0);
        assertThat(posts.getTitle()).isEqualTo(title);
        assertThat(posts.getContent()).isEqualTo(content);

    }

}

H2 ์ฟผ๋ฆฌ ๋Œ€์‹  SQL ์ฟผ๋ฆฌ ๋กœ๊ทธ๋กœ ๋‚จ๊ธฐ๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ์ถ”๊ฐ€

spring.jpa.properties.hibernate.format_sql=true

๐Ÿƒ ๋“ฑ๋ก,์ˆ˜์ •,์กฐํšŒ API ๋งŒ๋“ค๊ธฐ ๐Ÿƒ

- Request ๋ฐ์ดํ„ฐ ๋ฐ›์„ DTO

- API ์š”์ฒญ์„ ๋ฐ›์„ Controller

- ํŠธ๋žœ์žญ์…˜,๋„๋ฉ”์ธ ๊ธฐ๋Šฅ ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” Service

 

 

Service๋Š” ๋น„์ฆˆ๋‹ˆ์Šค๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณณ์ด ์•„๋‹ˆ๋‹ค.
ํŠธ๋žœ์žญ์…˜, ๋„๋ฉ”์ธ ๊ฐ„ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ์—ญํ• ๋งŒ ํ•œ๋‹ค.

 

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ๊ณณ์€ ๋ฐ”๋กœ Domain์ด๋‹ค.

 

 

* ๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด *

์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ฐ€์ง€๊ณ , ๊ฐ์ฒด์ง€ํ–ฅ์˜ ํŠน์„ฑ์„ ์ ๊ทน ํ™œ์šฉํ•˜๋Š” ํŒจํ„ด
ํŠธ๋žœ์žญ์…˜ ์Šคํฌ๋ฆฝํŠธ (Service์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ


๐Ÿ“Œ ๋“ฑ๋ก Controller

@RequiredArgsConstructor
@RestController
public class PostApiController {
    private final PostsService postsService;

    @PostMapping("/api/v1/posts")
    public Long save(@RequestBody PostSaveRequestDto requestDto)
    {
        return postsService.save(requestDto);
    }

}

๐Ÿ“Œ ๋“ฑ๋ก Service

@RequiredArgsConstructor
@Service
public class PostsService {

    private final PostsRepository postsRepository;

    @Transactional
    public Long save(PostSaveRequestDto requestDto) {
        return postsRepository.save(requestDto.toEntity()).getId();
    }
}

๐Ÿ“Œ ๋“ฑ๋ก RequestDto

@Getter
@NoArgsConstructor
public class PostSaveRequestDto {

    private String title;
    private String content;
    private String author;

    @Builder
    public PostSaveRequestDto(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

    //DTO -> Posts Entity๋กœ
    public Posts toEntity()
    {
        return Posts.builder()
                .title(title)
                .content(content)
                .author(author)
                .build();
    }
}

๐Ÿ“Œ ๋“ฑ๋ก ํ…Œ์ŠคํŠธ

 

JPA ๊ธฐ๋Šฅ๊นŒ์ง€ ํ•œ๋ฒˆ์— ํ…Œ์ŠคํŠธํ•  ๋•Œ์—๋Š” @SpringBootTest ์™€ @TestRestTemplate๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค๊ณ ํ•œ๋‹ค.

Random port๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋‚ด์žฅ ํ†ฐ์บฃ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostApiControllerTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Autowired
    private PostsRepository postsRepository;

    @After
    public void teardown() throws Exception{
        postsRepository.deleteAll();
    }

    @Test
    public void Posts_๋“ฑ๋ก๋œ๋‹ค() throws Exception{
        //given
        String title ="title";
        String content ="content";
        PostSaveRequestDto postSaveRequestDto= PostSaveRequestDto.builder()
                .title(title)
                .content(content)
                .author("author")
                .build();

        String url="http://localhost:" + port + "/api/v1/posts";

        //when
        ResponseEntity<Long> responseEntity = testRestTemplate.postForEntity(url, postSaveRequestDto, Long.class);

        //then
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);

        List<Posts> postsList = postsRepository.findAll();
        assertThat(postsList.get(0).getTitle()).isEqualTo(title);
        assertThat(postsList.get(0).getContent()).isEqualTo(content);
    }
}

๐Ÿ”— @SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM_PORT)

 

๐Ÿ”— @LocalServerPort

 

๐Ÿ”— @TestRestTemplate

 

๐Ÿ”— restTemplate.postForEntity( ์š”์ฒญ ๋ณด๋‚ผ url, ๋ณด๋‚ผ ๊ฐ์ฒด, ๋ฐ›์•„์˜ฌ ํƒ€์ž…์˜ class)

 

๐Ÿ”— responseEntity.getBody()

 


์ˆ˜์ •๊ณผ ์กฐํšŒ์— ๋Œ€ํ•œ ๋ถ€๋ถ„์€

update ๋ถ€๋ถ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•œ ๋ถ€๋ถ„์—์„œ ๋ณด๊ณ  ๋„˜์–ด๊ฐ€์•ผ ํ•  ๋ถ€๋ถ„์ด ์žˆ์–ด์„œ ๊ทธ ๋ถ€๋ถ„๋งŒ ์ •๋ฆฌํ•ด๋‘๋ ค๊ณ ํ•œ๋‹ค.

 

๐Ÿ“Œ์ˆ˜์ • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

@Test
    public void Posts_์ˆ˜์ •๋œ๋‹ค() throws Exception{
        //given
        Posts posts= postsRepository.save(Posts.builder()
                .title("title")
                .content("content")
                .author("author")
                .build());

        Long updateId=posts.getId();
        PostsUpdateRequestDto requestDto =PostsUpdateRequestDto.builder()
                .title("fixed_title")
                .content("fixed_content")
                .build();


        String url="http://localhost:"+ port +"/api/v1/posts/"+ updateId;

        HttpEntity<PostsUpdateRequestDto> requestEntity = new HttpEntity<>(requestDto);

        //when
        ResponseEntity<Long> responseEntity = testRestTemplate.exchange(url, HttpMethod.PUT, requestEntity, Long.class);


        //then
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);

        List<Posts> postsList = postsRepository.findAll();
        assertThat(postsList.get(0).getTitle()).isEqualTo(requestDto.getTitle());
        assertThat(postsList.get(0).getContent()).isEqualTo(requestDto.getContent());
       
    }

๐Ÿ”— new HttpEntity<>( )

 

๐Ÿ”— restTemplate.exchange(url, HttpMethod.PUT, HttpEntity๋กœ ๊ฐ์‹ธ์ง„ ๊ฐ์ฒด, ๋ฐ˜ํ™˜ํƒ€์ž…)

 

728x90
Comments