API만들기(게시글 등록기능)
API란?
API(Application Programming Interface, 응용 프로그램 프로그래밍 인터페이스)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.
위 그림과 같이 비유하면, 손님은 메뉴에 있는 음식을 요청하는 응용프로그램이라면 셰프는 요리를 만들어 전달하는 운영체제라고 할 수 있다. 이 둘을 연결해주는 웨이터가 바로 API이다.
이제 게시판의 글 등록, 수정, 삭제 기능을 만들어 볼것이다.
- PostsApiController
@RequiredArgsConstructor
@RestController
public class PostsApiController {
private final PostsService postsService;
@PostMapping("/api/v1/posts")
public Long save(@RequestBody PostsSaveRequestDto requestDto){
return postsService.save(requestDto);
}
}
- PostsService
@RequiredArgsConstructor
@Service
public class PostsService{
private final PostsRepository postsRepository;
@Transactional
public Long save(PostsSaveRequestDto requestDto){
return Long save(PostsSaveRequestDto requestDto){
return postsRepository.save(requestDto.toEntity()).getId();
}
}
}
Controller와 Service에서 사용할 Dto 클래스를 만들거다.
@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
private String title;
private String content;
private String author;
@Builder
public PostsSaveRequestDto(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
public Posts toEntity() {
return Posts.builder()
.title(title)
.content(content)
.author(author)
.build();
}
}
Entity클래스를 Request/Response클래스로 사용하면 안되기 때문에 Entity클래스와 거의 유사함에도 불구하고 Dto클래스를 새로 추가로 생성했다.
이제 등록기능의 코드가 완성되었으니 등록기능에 대한 테스트 코드로 검증할것이다.
- PostsApiControllerTest
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostsApiControllertTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private PostsRepository postsRepository;
@After
public void tearDown() throws Exception {
postsRepository.deleteAll();
}
@Test
@WithMockUser(roles="USER")
public void Posts_등록() throws Exception {
//given
String title = "title";
String content = "content";
PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
.title(title)
.content(content)
.author("author")
.build();
String url = "http://localhost:" + port + "/api/v1/posts";
//when
ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url, requestDto, Long.class);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.Ok);
assertThat(responseEntity.getBody()).isGreaterThan(0L);
//then
List<Posts> all = postsRepository.findAll();
assertThat(all.get(0).getTitle()).isEqualTo(title);
assertThat(all.get(0).getContent()).isEqualTo(content);
}
}
API Controller를 테스트 하는데 HelloController와 달리 @WebMvcTest를 사용하지 않았는데, @WebMvcTest의 경우 JPA기능이 작동하지 않기 때문인데, Controller와 ControllerAdvice 등 외부 연동과 관련된 부분만 활성화되어 지금 같이 JPA기능까지 한번에 테스트 할때는 @SpringBootTest와 TestRestTemplate을 사용하면 된다.
그럼 이제 등록기능 테스트 완료!!!