1. REST level ?
흔히 사용하는 REST API 는 URL 을 통해 자원에 대해 표현하고 HTTP method 를 통해 자원의 행위를 정의한다. 하지만 이와 같은 방법은 클라이언트가 서버에서 제공하는 선택사항을 클라이언트의 선택에 의해 주도된다는 점이다. 우리가 아는 REST API는 해당 응답에 대한 다음 스텝에 대해 알려주지 않는다.
RESTful WEB API에 설명된 Richardson Maturity Model(RMM)에서 제공하는 4가지 레벨을 살펴보자.
- level0
- API 구현은 HTTP protocol 을 사용하지만 모든 기능을 활용하지 않는다.
- 리소스에 관한 고유 주소를 제공하지 않는다.
- level1
- 리소스에 대한 고유 식별자가 있지만, 리소스에 대한 각 행동(action)에도 고유한 URL이 있습니다.
- level2
- URL에 행동(action) 을 설명하는 동사 대신 HTTP Method 를 사용한다.
- 현재 가장 많이 활용되고 있는 REST API 형태이다.
- level3
- 리소스에 하이퍼미디어(Hypermedia) 를 도입하였다.
- 이를 통해 가능한 작업에 대해 알려주는 링크를 응답에 배치하여 API 를 탐색할 수 있는 기능을 추가할 수 있다.

2. HATEOAS ?
HATEOAS(Hypermedia as the Engine of Application State) 는 RMM 에서 제공하는 모델 중 level3 에 해당하는 방법이다. HATEOS 는 REST API 를 쉽게 탐색할 수 있도록 해주는 서비스이다. HATEOS 를 사용하면 다른 리소스를 가리키는 임베디드 URI 에 따라 API 를 탐색하고 상호 작용할 수 있다.
- HAL(Hypertext Application Language) 는 JSON 또는 XML 코드 내에서 외부 리소스에 대한 링크와 같은 하이퍼미디어를 정의하기 위한 규칙이다.
HTTP/1.1 200 OK
Content-Type: application/hal+json
{
"status" : "SUCCESS",
"data" : {
"studentId" : 1,
"name" : "홍길동",
"birthDate" : "2006-01-01",
"links": [
{
"rel": "self",
"href": "<http://localhost:8080/api/v1/students/0>"
},
{
"rel": "9th grade Link",
"href": "<http://localhost:8080/api/v1/students/0/grades/9>"
},
{
"rel": "10th grade Link",
"href": "<http://localhost:8080/api/v1/students/0/grades/10>"
},
{
"rel": "11th grade Link",
"href": "<http://localhost:8080/api/v1/students/0/grades/11>"
}
]
}
}
3. Spring HATEOS 를 제공한다.
Spring 에서는 Spring HATEOS 의존성을 제공하며 Representation models 을 통해 링크를 추가할 수 있는 기능을 제공한다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
}
@RestController
class EmployeeController {
...
@GetMapping("/employees/{id}")
ResponseEntity<Resource<Employee>> findOne(@PathVariable long id) {
return repository.findById(id)
.map(employee -> new Resource<>(employee, getSingleItemLinks(employee.getId())))
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
HATEOAS 가 진보적인 API 방식인가??
아직 주변에서 HATEOAS 를 실무에서 사용하는 경우를 보지 못했다. GraphQL and REST Level 3 (HATEOAS) 에서는 고객의API 사용 패턴과 호출 방식을 고려할 때 HATEOAS 보다 더 나은 대안(e.g. SDK, GraphQL API) 이 있다는 점이다. 고객들은 특정 사용 사례에 필요한 일부 API 만을 사용하므로 인라인 문서화가 큰 가치를 제공하지 못한다고 한다. 이 또한 트레이드 오프일 수 있다고 생각한다. 비즈니스 특성과 상황에 맞게 HATEOAS 를 도입하는 방법 또한 괜찮은 대안일 것이다.
Reference
- https://techblog.commercetools.com/graphql-and-rest-level-3-hateoas-70904ff1f9cf
- https://spring.io/blog/2018/01/12/building-richer-hypermedia-with-spring-hateoas
- https://en.wikipedia.org/wiki/Hypertext_Application_Language
- https://docs.spring.io/spring-hateoas/docs/current/reference/html/
- https://grapeup.com/blog/how-to-build-hypermedia-api-with-spring-hateoas/#
1. REST level ?
흔히 사용하는 REST API 는 URL 을 통해 자원에 대해 표현하고 HTTP method 를 통해 자원의 행위를 정의한다. 하지만 이와 같은 방법은 클라이언트가 서버에서 제공하는 선택사항을 클라이언트의 선택에 의해 주도된다는 점이다. 우리가 아는 REST API는 해당 응답에 대한 다음 스텝에 대해 알려주지 않는다.
RESTful WEB API에 설명된 Richardson Maturity Model(RMM)에서 제공하는 4가지 레벨을 살펴보자.
- level0
- API 구현은 HTTP protocol 을 사용하지만 모든 기능을 활용하지 않는다.
- 리소스에 관한 고유 주소를 제공하지 않는다.
- level1
- 리소스에 대한 고유 식별자가 있지만, 리소스에 대한 각 행동(action)에도 고유한 URL이 있습니다.
- level2
- URL에 행동(action) 을 설명하는 동사 대신 HTTP Method 를 사용한다.
- 현재 가장 많이 활용되고 있는 REST API 형태이다.
- level3
- 리소스에 하이퍼미디어(Hypermedia) 를 도입하였다.
- 이를 통해 가능한 작업에 대해 알려주는 링크를 응답에 배치하여 API 를 탐색할 수 있는 기능을 추가할 수 있다.

2. HATEOAS ?
HATEOAS(Hypermedia as the Engine of Application State) 는 RMM 에서 제공하는 모델 중 level3 에 해당하는 방법이다. HATEOS 는 REST API 를 쉽게 탐색할 수 있도록 해주는 서비스이다. HATEOS 를 사용하면 다른 리소스를 가리키는 임베디드 URI 에 따라 API 를 탐색하고 상호 작용할 수 있다.
- HAL(Hypertext Application Language) 는 JSON 또는 XML 코드 내에서 외부 리소스에 대한 링크와 같은 하이퍼미디어를 정의하기 위한 규칙이다.
HTTP/1.1 200 OK
Content-Type: application/hal+json
{
"status" : "SUCCESS",
"data" : {
"studentId" : 1,
"name" : "홍길동",
"birthDate" : "2006-01-01",
"links": [
{
"rel": "self",
"href": "<http://localhost:8080/api/v1/students/0>"
},
{
"rel": "9th grade Link",
"href": "<http://localhost:8080/api/v1/students/0/grades/9>"
},
{
"rel": "10th grade Link",
"href": "<http://localhost:8080/api/v1/students/0/grades/10>"
},
{
"rel": "11th grade Link",
"href": "<http://localhost:8080/api/v1/students/0/grades/11>"
}
]
}
}
3. Spring HATEOS 를 제공한다.
Spring 에서는 Spring HATEOS 의존성을 제공하며 Representation models 을 통해 링크를 추가할 수 있는 기능을 제공한다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
}
@RestController
class EmployeeController {
...
@GetMapping("/employees/{id}")
ResponseEntity<Resource<Employee>> findOne(@PathVariable long id) {
return repository.findById(id)
.map(employee -> new Resource<>(employee, getSingleItemLinks(employee.getId())))
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
HATEOAS 가 진보적인 API 방식인가??
아직 주변에서 HATEOAS 를 실무에서 사용하는 경우를 보지 못했다. GraphQL and REST Level 3 (HATEOAS) 에서는 고객의API 사용 패턴과 호출 방식을 고려할 때 HATEOAS 보다 더 나은 대안(e.g. SDK, GraphQL API) 이 있다는 점이다. 고객들은 특정 사용 사례에 필요한 일부 API 만을 사용하므로 인라인 문서화가 큰 가치를 제공하지 못한다고 한다. 이 또한 트레이드 오프일 수 있다고 생각한다. 비즈니스 특성과 상황에 맞게 HATEOAS 를 도입하는 방법 또한 괜찮은 대안일 것이다.
Reference
- https://techblog.commercetools.com/graphql-and-rest-level-3-hateoas-70904ff1f9cf
- https://spring.io/blog/2018/01/12/building-richer-hypermedia-with-spring-hateoas
- https://en.wikipedia.org/wiki/Hypertext_Application_Language
- https://docs.spring.io/spring-hateoas/docs/current/reference/html/
- https://grapeup.com/blog/how-to-build-hypermedia-api-with-spring-hateoas/#