[사이드프로젝트] 그저 그런 REST API로 괜찮은가? - 진정한 REST API 구현해보기 - Event Paging 불러오기
Event Read All 테스트 구현
이번에는 Event를 Paging을 사용해서 10개씩 가져오는 기능을 구현할 것이다.
그와 관련해서 고려해야 할 사항은 다음과 같다.
- Paging이 제대로 이뤄지는가.
- Paging을 통해 받은 Result도 HATEAOS를 만족하는가.
- Page 내의 Event들이 HATEAOS를 만족하는가.
이를 테스트 코드로 구현하면 다음과 같다.
@Test
public void get_sorted_event_list_by_paging() throws Exception {
// Given
IntStream.range(1,30).forEach( i ->{
Event event = createEvent(i);
this.eventRepository.save(event);
});
//When
//Then
mockMvc.perform(get("/api/events")
.param("page","1")
.param("size","10")
.param("sort", "name,DESC")
)
.andDo(print())
.andExpect(status().isOk())
// Result가 HATEOAS를 만족하는가
.andExpect(jsonPath("_links").exists())
// 제대로 Paging이 이뤄졌는가
.andExpect(jsonPath("page").exists())
// Page 내의 Event들도 제대로 HATEAOS를 만족하는가.
.andExpect(jsonPath("_embedded.eventResourceList.[0]._links.self").exists());
}
Serivce 수정
Page를 통해서 Event를 읽어오는 readWithPage 기능구현과 함께 create 기능 일부를 수정했다.
- create()내에서 Event -> EventResource로 바꿔서 반환했는데 이를 Event로 반환하도록 바꿈 -> Controller에서 EventResource 변환 및 URI 연결을 담당하도록 하기 위해서
package com.carrykim.restapi.event.service;
import com.carrykim.restapi.event.infra.EventJpaRepository;
import com.carrykim.restapi.event.infra.EventRepository;
import com.carrykim.restapi.event.model.Event;
import com.carrykim.restapi.event.model.dto.EventDto;
import com.carrykim.restapi.event.model.dto.EventResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.PagedModel;
import org.springframework.stereotype.Service;
@Service
public class EventService {
private final EventRepository eventRepository;
public EventService(EventRepository eventRepository) {
this.eventRepository = eventRepository;
}
public Event create(EventDto eventDto){
Event newEvent = eventDto.toModel();
return eventRepository.save(newEvent);
}
public Page<Event> readWithPage(Pageable pageable){
return this.eventRepository.findAll(pageable);
}
}
Controller 수정
- Controller에서 Event -> EventResource 변환 및 URI 매핑 담당,
- URI 매핑 부분을 addLink() 메소드로 분리
package com.carrykim.restapi.event.controller;
import com.carrykim.restapi.event.model.Event;
import com.carrykim.restapi.event.model.dto.EventDto;
import com.carrykim.restapi.event.model.dto.EventResource;
import com.carrykim.restapi.event.service.EventService;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.net.URI;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@RestController()
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)
public class EventController {
private final EventService eventService;
public EventController(EventService eventService) {
this.eventService = eventService;
}
@PostMapping("")
public ResponseEntity create(@RequestBody @Valid EventDto eventDto) {
Event event = this.eventService.create(eventDto);
EventResource eventResource = new EventResource(event);
addLinks(eventResource);
URI uri = linkTo(methodOn(EventController.class)
.create(new EventDto()))
.slash(eventResource.getEvent().getId()).toUri();
return ResponseEntity.created(uri).body(eventResource);
}
@GetMapping("")
public ResponseEntity readAll(Pageable pageable, PagedResourcesAssembler pagedResourcesAssembler) {
var result = pagedResourcesAssembler
.toModel(this.eventService.readWithPage(pageable).map(event -> {
EventResource eventResource = new EventResource(event);
addLinks(eventResource);
return eventResource;
}));
return ResponseEntity.ok(result);
}
private void addLinks(EventResource eventResource){
WebMvcLinkBuilder selfAndUpdateLink = linkTo(methodOn(EventController.class)
.create(new EventDto()))
.slash(eventResource.getEvent().getId());
WebMvcLinkBuilder queryLink = linkTo(methodOn(EventController.class));
eventResource.add(queryLink.withRel("query-events"));
eventResource.add(selfAndUpdateLink.withRel("update-event"));
eventResource.add(selfAndUpdateLink.withSelfRel());
}
}
테스트 결과
Author And Source
이 문제에 관하여([사이드프로젝트] 그저 그런 REST API로 괜찮은가? - 진정한 REST API 구현해보기 - Event Paging 불러오기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@carrykim/사이드프로젝트-그저-그런-REST-API로-괜찮은가-진정한-REST-API-구현해보기-Event-Paging-불러오기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)