REST API 만들기-4

스프링 기반 REST API 개발 -백기선님 인프런 강좌를 보고 작성하였습니다.

입력값 제한하기

현재 API는 입력값으로 id 또는 입력 받은 데이터를 가지고 계산해야하는 값까지도 입력으로 줄 수가 있습니다.

이번 포스팅에서는 입력으로 받으면 안되는 값들을 EventDTO를 적용하여 제한하는 방법에 대해서 알아보겠습니다.

EventDTO

Event 클래스에 어노테이션을 추가해서 DTO로 분리하는것과 같은 기능을 할 수는 있지만, 그런경우에 도메인 클래스에 너무 많은 어노테이션이 추가 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
@Builder @NoArgsConstructor @AllArgsConstructor @Data
public class EventDto {
private String name;
private String description;
private LocalDateTime beginEnrollmentDateTime;
private LocalDateTime closeEnrollmentDateTime;
private LocalDateTime beginEventDateTime;
private LocalDateTime endEventDateTime;
private String location; // (optional) 이게 없으면 온라인 모임
private int basePrice; // (optional)
private int maxPrice; // (optional)
private int limitOfEnrollment;
}

받기로 한 값들만 가지고 EventDTO 클래스를 만듭니다.

ModelMapper

입력 타입을 DTO로 바꿧으니 DTO를 다시 Event 객체로 변경해주어야 Event 타입으로 바꿔 주어야 EventRepository 를 쓸수 있습니다.

EventDTO 객체를 Event객체로 바꿔주려면 직접 옮기는 방법도 있지만 ModelMapper 를 사용해 쉽게 바꿔줄수 있습니다.

pom.xml

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.1</version>
</dependency>

빈등록

1
2
3
4
@Bean
public ModelMapper modelMapper(){
return new ModelMapper();
}

EventController

1
2
3
4
5
6
7
8
9
10
 private final ModelMapper modelMapper;

public EventController(EventRepository eventRepository, ModelMapper modelMapper){
this.eventRepository = eventRepository;
this.modelMapper = modelMapper;
}
```
생성자를 통해 ModelMapper 주입을 받습니다.
```java
Event event = modelMapper.map(eventDto,Event.class);

이렇게 ModelMapper를 통해 Event 객체로 변환할 수 있습니다.

EventControllerTests

테스트에서 더이상 테스트에서 만든 Event객체를 쓰지 않기 때문에 Mockito를 사용해서 Stubbing 하는 기능이 적용되지 않습니다.

그래서 이제 @WebMvcTest 어노테이션을 지우고 @SpringBootTest 와 SpringBootTest에서 MockMvc를 쓰기위해@AutoConfigureMock0Mvc 를 추가하여줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
mockMvc.perform(post("/api/events")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaTypes.HAL_JSON)
.content(objectMapper.writeValueAsString(event)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("id").exists())
.andExpect(header().exists(HttpHeaders.LOCATION))
.andExpect(header().string(HttpHeaders.CONTENT_TYPE,MediaTypes.HAL_JSON_UTF8_VALUE))
.andExpect(jsonPath("id").value(Machers.not(10)))
.andExpect(jsonPath("free").value(Machers.not(true)))
.andExpect(jsonPath("eventStatus").value(Machers.not(true)));

id, free, eventStatus 같은 입력으로 받아서 안되는 값들이 잘 제한됬는지 이렇게 코드를 추가하여 확인할 수 있습니다.