우리가 개발한 API를 사용하는 사용자 입장에서는 다양한 추가 정보를 한번에 얻을 수 있다는 장점이 있는
hateoas 에 대해 적용한다.
Level3 단계의 REST API 구현을 위한 HATEOAS 적용.
hateoas 기능을 사용하기 위해서
1. pom.xml에 내용을 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
2. 사용중인 버전 확인하기
sping 버전에 따라서 작성하는 코드가 상이하다.
버전 | ||
2.1.8.RELEASE 일 경우 | Resource | ControllerLinkBuilder |
2.2 그 이상 | EntityModel | WebMvcLinkBuilder |
버전은 pom.xml 파일의 상단부근에 하기와 같이 나와있으니 버전을 찾아 확인하면된다. 나는 2.4.10
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.10</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
나는 상위 버전이므로, Resource가 아닌 EntityModel을 사용해야한다.
사용할때 import는 당연히 hateoas 로
hateoas 사용법
retrieveUser 라는 함수를 이용해볼것이다.
입력한 id에 해당하는 사용자의 상세 조회된 데이터를 반환한다. 해당 id가 없을 경우엔 메세지를 반환한다.
목표 : 개별 사용자 목록 API에 hateoas 기능을 추가하고 전체 사용자 목록 API로 이동할 수 있게 함.
// 상세 조회를 할 사용자 GET
@GetMapping("/users/{id}")
public User retrieveUser(@PathVariable int id){
User user = service.findOne(id);
if (user == null) {
throw new UserNotFoundException(String.format("ID[%s] not found", id));
}
return user;
}
hateoas 구현(Code)
UserController.java
@GetMapping("/users")
public List<User> retrieveAllUsers(){
return service.findAll();
}
// 상세 조회를 할 사용자 GET
@GetMapping("/users/{id}")
public EntityModel retrieveUser(@PathVariable int id){
User user = service.findOne(id);
if (user == null) {
throw new UserNotFoundException(String.format("ID[%s] not found", id));
}
// HATEOAS
EntityModel<User> resource = new EntityModel<>(user);
// 이 user값을 반환시킬때 user가 사용할수 있는 추가적인 정보 링크를 하이퍼링크로 넣어놓을 예정
WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
resource.add(linkTo.withRel("all-users"));
return resource;
}
hateoas 결과(포스트맨)
resource.add(linkTo.withRel("all-users")); 로 인하여 all-users가 출력되었으며
hateoas 시, 해당 클래스의 retrieveAllUsers라는 상단에 있는 메소드를 링크하였다.
그렇기 때문에 href : 는 retrieveAllUsers 메소드에 어노테이션으로 작성된 @GetMapping("/users") 가 나온다.
코드는 수정하지 않았으나, 재 호출시, 출력 결과가 상이해짐. 둘다 맞겠지?..
개발하다 알게된 ... 기록용
사용하는데 이름이 너무 긴 method는 static import를 이용하여 줄이자!
[before] linkTo와 methodOn
WebMvcLinkBuilder linkTo = WebMvcLinkBuilder.linkTo(
WebMvcLinkBuilder.methodOn(this.getClass()).retrieveAllUsers());
[after] 코드 최상단에 static으로 import하여 주면 다음과 같은 코드 구현이 가능하다.
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
.
.
WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
내 코드에서 사용된 방법은 [후] 다.
import static은 한번 사용해보자. 인텔리제이에서는 쉽게 동작하지만, 이클립스는 따로 작성을 해줘야하는것같다.
'개발아닌개발 > springboot' 카테고리의 다른 글
Map<String, Object>의 안에 Object를 int로 바꾸는 방법 (2) | 2021.11.10 |
---|---|
[오류] JPA를 이용하여 UPDATE @query 사용 시, No results were returned by the query (0) | 2021.11.08 |
GetMapping 반복 - Scheduler 실습하기 (0) | 2021.11.08 |
User 내용 수정하는 PUTMapping (0) | 2021.11.08 |
SpringBoot 프로젝트 개요 (0) | 2021.11.05 |
댓글