Back-end/Spring

[SpringBoot] Spring Data JPA로 게시판 만들기(3) - 등록 API

poppy 2020. 11. 16. 16:10
반응형

이전 포스팅에 이어서 오늘은 등록 API를 만들어보겠습니다

 

1. 다음과 같이 패키지와 파일들을 만들어주세요

2. PostsSaveRequestDto

@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
    private String title;
    private String content;
    private String author;

    @Builder
    public PostsSaveRequestDto(String title, String content, String writer) {
        this.title = title;
        this.content = content;
        this.writer = writer;
    }

    public Posts toEntity() {
        return Posts.builder()
                .title(title)
                .content(content)
                .writer(writer)
                .build();
    }
}

※ Dto클래스가 Entitiy클래스와 거의 비슷한데 굳이 따로 만들어서 쓰는 이유가 무엇일까요?

Entity클래스는 Request/Response 클래스로 쓰면 안되고, Request/Response 클래스는 자주 변경이 됩니다. Entity클래스는 테이블과 연결되어 있기 때문에 Entity클래스를 변경하는 것은 큰 영향을 끼치는 변경이 됩니다. 따라서 Dto클래스를 Request/Response 클래스로 쓰고 Dto클래스는 자주 변경이 되어도 됩니다

 

@NoArgsConstructor - 기본 생성자를 추가해줍니다

@Builder - 이 클래스에 빌더패턴을 사용합니다

toEntity() - 이 메소드는 빌더패턴을 사용하여 title, content, writer 값을 가지는 객체를 리턴합니다

 

3. PostsService

@RequiredArgsConstructor
@Service
public class PostsService {
    private final PostsRepository postsRepository;

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

@RequiredArgsConstructor - final이 선언된 모든 필드를 인자값으로 하는 생성자를 생성해줍니다

@Service - 서비스 레이어, 비지니스 로직을 가진 클래스에 사용합니다

@Transactional - 트랜잭션을 설정합니다, ??

save() - requestDto의 toEntity메소드로 Posts 객체를 가져와 postRepository에 저장하고, id값을 리턴합니다????

 

4. PostsApiController

@RequiredArgsConstructor
@RestController
public class PostsApiController {
    private final PostsService postService;

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

@RequiredArgsConstructor - final이 선언된 모든 필드를 인자값으로 하는 생성자를 생성해줍니다

@RestController - 컨트롤러를 JSON으로 반환하는 컨트롤러로 만들어줍니다

@RequestBody - HTTP 요청 몸체를 자바 객체로 변환하는데 사용됩니다

 

 

5. PostsApiControllerTest

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostsApiControllerTest {
    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private PostsRepository postsRepository;

    @After
    public void tearDown() throws Exception {
        postsRepository.deleteAll(); //모든 데이터 삭제
    }

    @Test
    public void 등록() throws Exception {
        //given
        String title = "title";
        String content = "content";

        PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
                .title(title)
                .content(content)
                .writer("writer")
                .build();

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

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

        //then
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);
        List<Posts> all = postsRepository.findAll(); //모든 데이터 조회
        assertThat(all.get(0).getTitle()).isEqualTo(title);
        assertThat(all.get(0).getContent()).isEqualTo(content);

    }
}

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) - 테스트를 할 때 랜덤한 포트 번호로 실행한다는 의미입니다

@LocalServerPort -로컬서버의 포트번호를 나타냅니다

@Autowired - 빈을 자동으로 주입받습니다

@After - 단위 테스트가 끝날 때 수행되는 메소드를 지정하는 것입니다

 

TestRestTemplate

- 여러 테스트 종류 중 하나로, REST API 호출이후 응답을 받을 때까지 기다리는 동기방식입니다

@SpringBootTest와 TestRestTemplate을 사용하면 편리하게 웹 통합 테스트를 할 수 있습니다.

MockMvc와는 차이가 존재합니다. MockMvc는 Servlet Container를 생성하지 않는 반면, @SpringBootTest와 TestRestTemplate는 Servlet Container를 사용합니다. 그래서 마치 실제 서버가 동작하는 것처럼 테스트를 할 수 있는 것입니다

ResponseEntity - 헤더와 바디, 상태 코드로 구성되어 있고 http 응답을 나타낼 때 사용 합니다. Http 응답을 편하게 구성하여 보낼 때 사용 하는 클래스입니다

.postForEntity() - POST 요청을 보내고 결과로 ResponseEntity로 반환받습니다. postForEntity의 1번째 인자는 요청 url이고 2번째 인자는 post할 객체이며 3번째 인자는 response할 데이터의 타입 클래스입니다.

 

 

[참고]

advenoh.tistory.com/46

 

스프링 RestTemplate

Gatsby로 블로그 마이그레이션을 하여 이 링크를 클릭하면 해당 포스팅으로 갑니다. 감사합니다. http://blog.advenoh.pe.kr 1. 들어가며 스프링 프레임워크에서는 REST 서비스의 Endpoint를 호출할 수 있도

advenoh.tistory.com

goateedev.tistory.com/132

 

[ Springboot ] ResponseEntity 란

ResponseEntity 는 헤더와 바디, 상태 코드로 구성되어 있고 http 응답을 나타낼 때 사용 한다. Http 응답을 편하게 구성하여 보낼 떄 사용 하는 클래스 이다. ResponseEntity 는 HttpEntity( http 헤더, 바디 )..

goateedev.tistory.com

 

반응형