본문 바로가기
[ JAVA ]/JAVA RESTful API

[ RESTful API ] EntityModel 개념 및 예제

by 환이s 2023. 7. 24.


오늘은 RESTful API를 공부하던 중 사용하게 된 EntityModel <>에 대해 포스팅을 해보겠습니다.

 

EntityModel

 

EntityModel은 스프링 프레임워크에서 HATEOAS(Hypermedia as the Engine of Application State)를 지원하기 위해 도입된 클래스입니다. HATEOAS는 RESTful API에서 클라이언트와 서버 간 상호작용을 위해 하이퍼미디어를 사용하는 개념을 강조하는 아키텍처 스타일입니다. 또한

리소스를 표현하는 데 사용되는 클래스로, Spring HATEOAS 라이브러리에서 제공하는 클래스 중 하나입니다.

 

하나의 Entity(data)를 표현하는 데 사용되며, 해당 Entity의 데이터와 함께 Hypermedia Links를 포함할 수 있습니다. Hypermedia Links를 통해 리소스 간의 관계와 API 상태 전이를 나타낼 수 있어 클라이언트가 API를 더 쉽게 이해하고 활용할 수 있게 됩니다.

 

예를 들어, 간단한 도메인 모델을 가정해 보겠습니다.

 

사용자(User)를 표현하는 데이터 모델이 있고, 이 사용자가 데이터에 대한 RESTful API를 구현하고자 합니다. 이때 EntityModel을 사용하면 다음과 같이 데이터와 링크를 조압하여 리소스를 반환할 수 있습니다.

 

@Data
public class User {
    private Long id;
    private String username;
    private String email;

   
}

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public EntityModel<User> getUser(@PathVariable Long id) {
        // 사용자 정보를 데이터베이스나 다른 곳에서 가져온다고 가정
        User user = userService.getUserById(id);

        // EntityModel을 사용하여 사용자 정보를 반환하고, self 링크를 추가함
        return EntityModel.of(user,
                linkTo(methodOn(UserController.class).getUser(id)).withSelfRel());
    }
}

 

'EntityModel.of(user, linkTo(...))'를 사용하여 사용자 정보를 EntityModel로 감싸주고, 'linkTo(...)'를 사용하여 self 링크를 추가했습니다. 이렇게 하면 클라이언트는 사용자 정보와 함께 self 링크를 통해 해당 사용자에 대한 자원에 대한 URL을 받게 됩니다.

 

클라이언트는 이러한 링크들을 이용하여 다른 리소스와의 관계를 파악하고 API를 탐색할 수 있게 됩니다.

 

추가로 HATEOAS 라이브러리를 지원해 주는  WebMvcLinkBuilder 클래스도 알아봅시다.

 


WebMvcLinkBuilder 

 

WebMvcLinkBuilder는 앞서 말씀드린 것처럼 HAtEOAS를 지원하기 위해 사용되는 클래스 중 하나입니다.

 

RESTful API에서 클라이언트와 서버 간 상호작용을 위해 하이퍼미디어를 사용하는 개념을 강조하는 아키텍처 스타일입니다. WebMvcLinkBuilder의 주요 역할은 하이퍼미디어 링크를 생성하여 리소스 간의 관계를 표현하는 데 사용되고, 컨트롤러 메서드의 반환값이나 다른 리소스와 관련된 링크를 생성하기 위해 주로 사용됩니다.

 

특히, 'linkTo()' 메서드는 컨트롤러 메서드를 기반으로 하이퍼미디어 링크를 생성하는 데 사용됩니다.

 

예를 들어, 사용자(User) 정보를 반환하는 RESTful API 컨트롤러를 작성한다고 가정해 봅시다. 이때, WebMvcLinkBuilder를 사용하여 사용자 정보와 self 링크를 함께 반환할 수 있습니다.

 

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public EntityModel<User> getUser(@PathVariable Long id) {
        // 사용자 정보를 데이터베이스나 다른 곳에서 가져온다고 가정
        User user = userService.getUserById(id);

        // EntityModel을 사용하여 사용자 정보를 반환하고, self 링크를 추가함
        return EntityModel.of(user,
            WebMvcLinkBuilder.linkTo(methodOn(UserController.class).getUser(id)).withSelfRel());
    }
}

위 코드에서 'WebMvcLinkBuilder.linkTo(methodOn(UserController.class). getUser(id))'를 사용하여 self 링크를 생성하고, 'withSelfRel()'를 사용하여 self 링크의 관계를 지정했습니다.

 

이렇게 하면 클라이언트는 사용자 정보를 받아오는 동시에 self 링크를 얻어서 해당 사용자 리소스에 대한 URL을 알 수 있습니다.

 

WebMvcLinkBuilder는 링크 생성뿐만 아니라, 다른 컨트롤러 메서드와의 관계를 정의하거나 커스텀 링크를 생성하는 데에도 사용될 수 있습니다. 이를 통해 RESTful API를 확장하고 클라이언트가 리소스 간의 관계를 파악하고 탐색할 수 있도록 도와줍니다.

 

마지막으로 간단한 예제 코드를 통해서 알아봅시다.


예제 코드

 

예제 코드로는 특정 사용자의 정보를 조회하고, Spring Boot 기반으로 JPA를 사용한 RESTful API의 컨트롤러 메서드입니다.

 

@GetMapping("/users/{id}")
public EntityModel<User> retrieveUser(@PathVariable int id){
    Optional<User> user = userRepository.findById(id);

    if (!user.isPresent()){ // 데이터가 없다면?
        throw new UserNotFoundException(String.format("ID[%s] not found" , id));
    }

    EntityModel<User> model = EntityModel.of(user.get());
    WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
    model.add(linkTo.withRel("all-users"));

    return model;
}

 

위 코드를 해석해 보면 '/users/{id}' 경로로 GET 요청이 들어왔을 때 실행되며, 특정 사용자의 정보를 조회하여 반환합니다. 해당 메서드는 EntityModel을 사용하여 사용자 정보와 함께 self 링크와 "all-users"라는 이름의 링크를 추가하여 응답합니다. 즉, EntityModel 객체를 반환하는 것을 의미합니다.

 

Optional<User> user = userRepository.findById(id);

이 부분은 'userrepository'에서 주어진 'id'로 사용자 정보를 조회하고 'id'에 해당하는 사용자를 찾으면 'Optional.empty()'를  반환해 주고, if문을 통해서 데이터가 조회되지 않은 경우 예외를 던집니다.

 

또한, 

linkTo(methodOn(this.getClass()).retrieveAllUsers())

현재 클래스에서 retrieveAllUsers() 메서드에 대한 링크를 생성하고, 'model'에 객체를 추가하고 반환합니다.

 

결과로는 PostMan으로 확인해 보겠습니다.

 

 

먼저 전체 조회를 해서 데이터를 확인해서 id = 1,2 값이 존재한 걸 확인했습니다.

그렇다면 경로에 먼저 id =1 값을 지정해 보겠습니다.

 

정상적으로 출력되고 링크까지 생성되는 걸 확인할 수 있습니다. 

다음으로는 id값에 100을 지정하고 Send 해보겠습니다. 데이터가 없기 때문에 예외가 발생해야 합니다.

 

정상적으로 데이터가 없기 때문에 404 Not Found 예외가 발생했습니다.

 


정리하자면

 

EntityModel은 Spring HATEOAS 라이브러리에서 제공하는 기능 중 하나이며, 더 복잡한 API에는 CollectionModel이나 RepresentationModel 등을 사용하여 여러 리소스 또는 컬렉션을 표현하는 데 활용할 수 있습니다. 

 

이러한 하이퍼미디어 기능을 통해 클라이언트와 서버 간의 상호작용이 유연하고 확장 가능하게 만들 수 있습니다.


마치며

 

오늘은 EntityModel , WebMvcLinkBuilder 클래스의 개념 및 사용 예제에 대해 알아봤습니다.

다음 포스팅에서 뵙겠습니다.

 

728x90