RestApi 만들기 - 이벤트 수정 API구현 (11)
- SPRING START!/restAPI😢
- 2021. 3. 11. 22:59
반응형
반응형
이번에는 강의를 듣기전에 먼저 작성하기로 해보자.
이벤트 수정의 경우는
1. 수정이 정상적으로 실행이 되었을때 : 200
2. 수정이 잘못된 경우
- 비어있는 객체가 들어있을 경우.
- 잘못된 객체가 들어올 경우..
- 권한이 없는 사람이 접근했을 경우
- 페이지가 존재하지 않는 경우
이렇게 들 수 있는데... 솔직히 2-3은 지금당장은 하지 못할 것 같다.
왜냐하면 유저를 고려하지 않았기 때문이다.
테스트 코드를 작성해보자.
@Test
void update_event() throws Exception {
Delivery delivery = generateEvent(100);
DeliveryDto deliveryDto = modelMapper.map(delivery, DeliveryDto.class);
deliveryDto.setItem("book");
deliveryDto.setUser("klom2");
deliveryDto.setItemPrice(1000);
deliveryDto.setDeliveryTime(LocalDateTime.now());
deliveryDto.setDeliveryEndTime(LocalDateTime.now().plusDays(10));
this.mockMvc.perform(put("/api/delivery")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(deliveryDto)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("id").exists())
.andExpect(jsonPath("user").value("klom2"))
.andExpect(jsonPath("_link.self").exists())
.andExpect(jsonPath("_link.profile").exists());
}
정상적인 경우 테스트에 성공하는 컨트롤러를 만들어보자.
@PutMapping("/{id}")
public ResponseEntity<?> updateEvent(@PathVariable Integer id) {
return ResponseEntity.ok().build();
}
이렇게 만들면 될까?
하지만 이렇게 만들면... id를 입력하지 않기 때문에 에러가 발생한다.
따라서..
@PutMapping("/{id}")
public ResponseEntity<?> updateEvent(@PathVariable Integer id) {
Optional<Delivery> optionalDelivery = deliveryRepository.findById(id);
Delivery delivery = optionalDelivery.get();
EntityModel<Delivery> entityModel = DeliveryModel.modelOf(delivery);
return ResponseEntity.ok(entityModel);
}
이렇게 수정했다.
하지만 이렇게 만드니 새로운 문제가 발생했다.
그래서 이렇게 수정했다.
@PutMapping("/{id}")
public ResponseEntity<?> updateEvent(@PathVariable Integer id,
@RequestBody @Valid DeliveryDto deliveryDto,Errors errors) {
Optional<Delivery> optionalDelivery = deliveryRepository.findById(id);
Delivery delivery = optionalDelivery.get();
Delivery map = modelMapper.map(deliveryDto, Delivery.class);
Delivery newDelivery = deliveryRepository.save(map);
EntityModel<Delivery> entityModel = DeliveryModel.modelOf(newDelivery);
return ResponseEntity.ok(entityModel);
}
이제 프로파일을 추가해보면...
테스트가 성공했다.
이제 다음 미션
수정이 잘못되었을 경우를 생각해보자.
비어있는 값일 경우에는
if (errors.hasErrors()) {
return errorResource(errors);
}
이것을 추가해주면 되었다.
값이 잘못된 경우에는
deliveryValidator.validate(deliveryDto, errors);
if (errors.hasErrors()) {
return errorResource(errors);
}
이걸 추가하면 되었다.!
최종적으로
@PutMapping("/{id}")
public ResponseEntity<?> updateEvent(@PathVariable Integer id,
@RequestBody @Valid DeliveryDto deliveryDto,
Errors errors) {
Optional<Delivery> optionalDelivery = deliveryRepository.findById(id);
if (errors.hasErrors()) {
return errorResource(errors);
}
deliveryValidator.validate(deliveryDto, errors);
if (errors.hasErrors()) {
return errorResource(errors);
}
Delivery delivery = optionalDelivery.get();
Delivery map = modelMapper.map(deliveryDto, Delivery.class);
Delivery newDelivery = deliveryRepository.save(map);
EntityModel<Delivery> entityModel = DeliveryModel.modelOf(newDelivery);
entityModel
.add(Link.of("http://localhost:8080/docs/index.html#update-event").withRel("profile"));
return ResponseEntity.ok(entityModel);
}
하 근데.. 너무 더럽긴 더럽다...ㅜㅜ
이따 리펙토링을 하자.
이제 doc으로 만들고 마치자..
@Test
void update_event() throws Exception {
Delivery delivery = generateEvent(100);
DeliveryDto deliveryDto = modelMapper.map(delivery, DeliveryDto.class);
deliveryDto.setItem("book");
deliveryDto.setUser("klom2");
deliveryDto.setItemPrice(1000);
deliveryDto.setDeliveryTime(LocalDateTime.now());
deliveryDto.setDeliveryEndTime(LocalDateTime.now().plusDays(10));
this.mockMvc.perform(put("/api/delivery/{id}", delivery.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(deliveryDto)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("id").exists())
.andExpect(jsonPath("user").value("klom2"))
.andExpect(jsonPath("_links.self").exists())
.andExpect(jsonPath("_links.profile").exists())
.andDo(document("update-event",
links(linkWithRel("query-events").description("이벤트 생성페이지로"),
linkWithRel("update-events").description("이벤트 수정페이지로"),
linkWithRel("self").description("해당 이벤트로 이동페이지로"),
linkWithRel("profile").description("해당 이벤트로 이동페이지로")),
requestHeaders(headerWithName(HttpHeaders.CONTENT_TYPE).description("현재 contentType"),
headerWithName(HttpHeaders.CONTENT_LENGTH).description("content 길이")),
requestFields(fieldWithPath("item").description("상품명"),
fieldWithPath("user").description("판매자"),
fieldWithPath("deliveryTime").description("판매일"),
fieldWithPath("deliveryEndTime").description("도착일"),
fieldWithPath("itemPrice").description("상품가격")),
responseHeaders(headerWithName(HttpHeaders.CONTENT_TYPE).description("현재 사용하고 있는 contentType")),
responseFields(fieldWithPath("id").description("this item id"),
fieldWithPath("item").description("바꿀 상품명"),
fieldWithPath("user").description("바꿀 유저이름"),
fieldWithPath("deliveryTime").description("출발 시간"),
fieldWithPath("deliveryEndTime").description("도착 시간"),
fieldWithPath("status").description("현재 상품 상태"),
fieldWithPath("itemPrice").description("상품 가격"),
fieldWithPath("deliveryCost").description("배송비"),
fieldWithPath("_links.query-events.href").description("목록페이지로"),
fieldWithPath("_links.update-events.href").description("수정페이지로"),
fieldWithPath("_links.self.href").description("현재페이지로"),
fieldWithPath("_links.profile.href").description("현재 링크로 이동"))));
}
어마어마하군..
중복된 부분과 쓸모없는 부분이 조금 보인다.
이제 리펙토링을 해야된다.
이거는 올리지 않을 예정...
그리고 나서 유저도 추가해주면 resapi끝!
반응형
'SPRING START! > restAPI😢' 카테고리의 다른 글
RestApi 만들기 - 스프링 시큐리티 설정 (13) (0) | 2021.03.23 |
---|---|
RestApi 만들기 - 스프링 시큐리티 적용하기 (12) (0) | 2021.03.17 |
RestApi 만들기 - 이벤트 조회 API구현 (10) (0) | 2021.03.09 |
RestApi 만들기 - 이벤트 목록 조회 API구현 (9) (0) | 2021.03.06 |
RestApi 만들기 - API인덱스 지점 만들기 (8) (0) | 2021.03.03 |