Kind of Magic

이전에 DAO 대신 Spring Data JPA 의 JpaRepository 를 사용하여 DAO 를 사용함에 따라 발생하는 boiler-plate code 의 문제를 해결했다. 그런데, 여기서 더 큰 마법을 수행할 수 있다.

REST Controller 도 Spring Data REST 에 의하여 대체될 수 있다.

Spring Data REST

Spring Data REST 는 아래의 endpoints 를 자동으로 expose 해준다.

HTTP MethodURICRUD Action
POST/employeesCreate a new employee
GET/employeesRead a list of employees
GET/employees/{employeeId}Read a single employee
PUT/employees/{employeeId}Update an existing employee
PATCH/employees/{employeeId}Partially update an employee
DELETE/employees/{employeeId}Delete an existing employee

Spring Data REST 는 기본적으로 simple plurailized form, 즉 entity type 의 복수형의 형태로 endpoints 를 expose 한다.

Spring Boot 가 실행되면, Spring Data REST 가 JPA Repository interface 를 스캔하여 자동으로 REST Controller 를 Proxy 형태로 생성한다.

사용 방법은 더 간단하다. 단순히 Maven POM file 에 spring-boot-starter-data-rest 를 추가해주면 끝이다. 더 이상의 code 는 필요하지 않다.

결과적으로 표면적인 Application Architecture 가 다음과 같이 간단해진다.

HATEOAS

Spring Data REST 에서 자동으로 생성되는 endpoints(REST API) 는 HATEOAS 원칙을 준수한다.

HATEOAS(Hypermedia As The Engine Of Application State) 는 REST API 의 한 구성 요소로, Server 가 Client 에게 data 뿐만 아니라 그 data 와 관련된 추가적인 행동(다음에 호출할 수 있는 API link 등)에 대한 정보를 Hypermedia(link) 형태로 함께 제공하는 개념이다.

즉, Client 가 Server 의 response 를 받을 때, 단순히 data 만 받는 것이 아니라 그 상태에서 취할 수 있는 다른 행동(예: update, delete, 다음 페이지 이동 등)에 대한 URI link 도 함께 받아, Client 가 별도의 API document 를 보지않고도 Server 와 dynamic 하게 상호작용할 수 있게 해준다.

예를 들어, 기존의 REST reqest 가 다음과 같다면,

{
  "id": 10,
  "subject": "게시글 10",
  "content": "내용"
}

HATEOAS 가 적용된 request 는

{
  "id": 100,
  "subject": "게시글 10",
  "content": "내용",
  "_links": {
    "self": { "href": "https://api.example.com/articles/10" },
    "next": { "href": "https://api.example.com/articles/11" },
    "comment": { "href": "https://api.example.com/articles/10/comments"}
  }
}
 

과 같기 때문에, 이처럼 request 에 포함된 link 를 따라 Client 가 쉽게 State Transition, 즉 페이지 내에서 다른 행동을 하도록 도와준다.

Redirection 하고는 다른 것이, Redirection 은 Server 가 Client 를 자동으로 다른 URL 로 이동시키나, HATEOAS 는 response 에 link(href) 를 포함시켜 Client 가 직접 이동하게 하는 것이다.

만약 GET /employees 와 같이 collection, 즉 여러 개의 data 를 request 하는 것에 대한 response 에는 기존의 data 뿐만 아니라, page size, total elements, totalPages 등의 meta-data 도 response 에 포함된다. 이는 Pagination(page 이동, 다음/이전 페이지) 을 구현하거나, 전체 data 양을 파악하는 데 도움이 된다.

Advanced Features

Spring Data REST 의 advanced features 는 다음과 같다.

  1. Pagination, sorting and searching
  2. Extending and adding custom quries with JPQL
  3. Query Domain Specific Language (Query DSL)
Spring Data REST - Test

위와 같이 GET /employees endpoint 가 expose 된 것을 볼 수 있다.

application.properties 에 다음 property 를 추가하여 base path 도 변경 가능하다.

spring.data.rest.base-path=/magic-api

위와 같이 변경된 base path 에 대하여 POST method 도 잘 적용된다.

또한, PUT 이나 PATCH method 를 사용할 때, Spring Data REST 는 id 를 오직 URL 에서만 사용 가능하다. 만약 id 값을 request body 에 포함시킨다면, 이에 대한 위험성은 여기서 확인 가능하다. 단순하게만 설명하면, Client 가 고의적으로나 실수로 기존 data 를 변경시킬 수 있기 때문이다.

위와 같이 PUT method 도 잘 작동하는 것을 볼 수 있다.

PATCH 도 잘 작동하며, 아래와 같이 DELETE 도 성공적으로 작동한다.

DELETE 에서, 이전의 Spring Boot version 에서는 default 로 204 No Content 를 return 하였지만, 최근의 Spring Boot version 에서는 200 OK 를 default 로 return 한다.

최근 Spring Boot 를 기준으로, request header 의 Accept variable 이 존재하지 않을 때만 204 No Content 를 return 하거나 별도의 configuration 을 통하여 return 값을 할 수 있다. 별도의 configuration 및 더 자세한 내용은 여기서 확인할 수 있다.

Postman 을 통하여 Accept variable 을 설정하지 않으면 아래와 같이 204 No Content 가 return 되는 것을 볼 수 있다.