똑같은 삽질은 2번 하지 말자
Spring으로 REST API No.4(Spring HATEOAS, ) 본문
HATEOAS 란?
어떤 계좌를 조회하는 요청이 있다.
GET /accounts/12345 HTTP/1.1
Host: bank.example.com
Accept: application/vnd.acme.account+json
그에 대한 응답
HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json
Content-Length: ...
{
"account": {
"account_number": 12345,
"balance": {
"currency": "usd",
"value": 100.00
},
"links": {
"deposit": "/accounts/12345/deposit",
"withdraw": "/accounts/12345/withdraw",
"transfer": "/accounts/12345/transfer",
"close": "/accounts/12345/close"
}
}
}
계좌에 돈이 있으므로 rel = 이체, 돈뽑기, 입금, 계좌닫기 등등 할 수 있다.
다른 계좌에 대한 응답으로
Content-Type: application/vnd.acme.account+json
Content-Length: ...
{
"account": {
"account_number": 12345,
"balance": {
"currency": "usd",
"value": -25.00
},
"links": {
"deposit": "/accounts/12345/deposit"
}
}
이번 계좌에는 돈이 -25.00달러 이므로 입금밖에 안된다.
이처럼 상태에 따라 링크의 정보가 바뀌는걸
Hypermedia as the Engine of Application State (HATEOAS) 라고 한다.
Spring HATEOAS는 이러한 링크 + 리소스를 쉽게 만들 수 있게 지원해준다.
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
public class EventResource extends Resource<Event>{ // 자동으로 Unwrapped 된다.
public EventResource(Event event, Link... links) {
super(event, links);
add(linkTo(EventController.class).slash(event.getId()).withSelfRel());
}
}
@PostMapping
public ResponseEntity createEvent(@RequestBody @Valid EventDto eventDto, Errors errors) {
if(errors.hasErrors())
return ResponseEntity.badRequest().body(errors);
eventValidator.validate(eventDto, errors);
if(errors.hasErrors())
return ResponseEntity.badRequest().body(errors);
Event event = modelMapper.map(eventDto,Event.class);
event.update();
Event newEvent = this.eventRepository.save(event);
URI createUri =
linkTo(EventController.class).slash(newEvent.getId()).toUri();
EventResource eventResource = new EventResource(event);
eventResource.add(linkTo(EventController.class).withRel("query-events"));
eventResource.add(linkTo(EventController.class).slash(newEvent.getId()).withRel("update-events"));
return ResponseEntity.created(createUri).body(eventResource);
// event는 자바빈 스펙을 준수하므로 BeanSerializer로 json으로 변환해서 자동으로 넘어간다.
}
링크정보를 담은 응답정보를 리턴..
그리고 ResourceSupport를 안쓰는 이유는 EventResource를 mapping을 object mapper가 serialization 할 때
BeanSerializer를 쓰는데 BeanSerializer는 기본적으로 그 객체의 이름으로 감싸서 보낸다.
@JsonUnwrapped 를 붙여서 보내도 되지만, Resource 에는 자동으로 붙여져 있으므로 안 붙여도 된다.
'Spring > Spring Boot' 카테고리의 다른 글
Spring Boot에서 전역 에러 핸들러 등록(@ControllerAdvice, @RestControllerAdvice, @ExceptionHandler) (0) | 2020.09.02 |
---|---|
Spring으로 REST API No.5(Spring REST Docs ) (0) | 2020.07.09 |
Spring으로 REST API No.3(입력값 제한, ModelMapper, @Valid, Errors, JsonSerializer ) (0) | 2020.06.29 |
Spring으로 REST API No.2(도메인구현, 기본 요청 응답(201)테스트, ) (0) | 2020.06.28 |
Spring으로 REST API No.1(REST API , 프로젝트 구성) (0) | 2020.06.28 |
Comments