슬기로운 개발생활

HATEOAS까지 사용해야 완벽한 RESTful이다.

by coco3o
반응형

나는 지금까지 REST API는 URI는 정보의 자원만 표현하고, 자원의 행위는 HTTP Method를 통해 명시한다는 것으로만 알고 사용하고 있었다.
위 내용도 물론 맞지만, 그건 반쪽짜리 REST API 였고, HATEOAS까지 알고 사용해야 진정한 REST API를 사용한다 할 수 있다.
그래서 이번엔 HATEOAS가 뭐고 어떤 특징이 있는지 알아보려 한다.

 

HATEOAS (Hypermidia As The Engine Of Application State)

HATEOAS(일명 헤이티오스)는 API를 실제로 "RESTful"하게 만드는 REST Appilcation Architecture의 제약 조건이다.
기본적으로 요청에 대해 서버는 응답에 데이터만 클라이언트에게 보내는데,
HATEOAS를 사용하면 응답에 데이터뿐만 아니라 해당 데이터와 관련된 요청에 필요한 URI를 응답에 포함하여 반환하며, 이는 REST API를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 해준다.
 

REST API 구현 단계

REST API를 구현하기 위한 단계가 존재하는데, 마지막 단계가 Hypermedia Controls - HATEOAS라는 개념을 통해서 자원에 호출 가능한 API 정보를 자원의 상태를 반영하여 표현하는 것이다.

https://grapeup.com/blog/how-to-build-hypermedia-api-with-spring-hateoas/#

  • 레벨 0
    HTTP 프로토콜을 사용하여 API를 구현하지만 모든 기능을 활용하지는 않는다. 또한 리소스에 대한 고유 주소는 제공되지 않는다.
    method: POST URI: /movie
  • 레벨 1
    리소스에 대한 고유 식별자가 있지만 리소스에 대한 각 작업에는 고유한 URL이 있다.
    method: POST URI: /movie/1/delete
  • 레벨 2
    동작을 설명하는 동사 대신 HTTP 메소드를 사용한다.
    method: DELETE URI: /movie/1
  • 레벨 3
    HATEOAS가 도입되었다. 간단히 말해서 리소스에 하이퍼미디어를 도입하며, 이를 통해 가능한 작업에 대해 알려주는 응답에 링크를 배치할 수 있으므로 API를 통해 탐색할 수 있는 가능성이 추가된다.
    method: DELETE URI: /movie/1

요즘 대부분의 프로젝트는 레벨 2를 사용하여 작성된다. 하지만 완벽한 RESTful API를 원한다면 HATEOAS를 고려해야 한다.
 

HATEOAS를 사용한 REST API 응답 형태

예를 들어, 게시글을 조회하는 URI가 있다고 가정해보자.

GET https://my-test-server.com/articles

기존 REST API application/json 응답 형태

{
    "id": 100,
    "subject": "게시글 100",
    "content": "내용",
    "self": "https://my-test-server.com/api/v1/articles/100"
}

여기서 해당 글을 조회한 사용자는 다음으로 어떤 행동을 할 수 있을까?

  • 다음 게시글 조회
  • 좋아요
  • 댓글 달기
  • 홈 이동

이런 행동들이 바로 상태 전이(State Transition)가 가능한 것들인데, 이것들을 응답 본문에 넣어줘야 한다는 소리다.

{
    "id": 100,
    "subject": "게시글 100",
    "content": "내용",
    "self": "https://my-test-server.com/api/articles/100",
    "next": "https://my-test-server.com/api/articles/101",
    "like": "https://my-test-server.com/api/articles/likes",
    "comment":"https://my-test-server.com/api/articles/100/comments",
    "home": "https://my-test-server.com/"
}

위와 같이 Hypermedia(링크)를 통해서 넣어주면, 클라이언트는 현재의 리소스에서 가능한 액션을 하이퍼미디어 링크를 참조하여 알 수 있고, 이를 따라가며 상태 전이를 쉽게 진행할 수 있다. 
 
하지만 아직 진정한 REST API라고는 할 수 없으며,
 
다음과 같이 링크와 관련된 리소스의 관계를 명확히 표현하는 표준적인 방법을 제공한다.
 

HAL

Hypertext Application Language으로 JSON, XML 코드 내의 외부 리소스에 대한 링크를 추가하기 위한 특별한 데이터 타입이다.
이 HAL 타입을 이용한다면 쉽게 HATEOAS를 달성할 수 있으며, 두 가지의 특징만 이용하면 된다.
1. 리소스 : 일반적인 데이터 필드에 해당한다.
2. 링크 : 하이퍼미디어로 보통 _self 필드가 링크 필드가 된다.
 
application/hal+json HATEOAS 응답 형태

{
    ~리소스 영역~
    "id": 100,
    "subject": "게시글 100",
    "content": "내용"
    ~리소스 영역~
    
    ~링크 영역~
    "_links" : {
        "self": {
            "href": "https://my-test-server.com/api/articles/100"
        },
        "next": {
            "href": "https://my-test-server.com/api/articles/101"
        },
        "like": {
            "href": "https://my-test-server.com/api/articles/likes"
        },
        "comment": {
            "href": "https://my-test-server.com/api/articles/100/comments" 
        },
        "home": {
            "href": "https://my-test-server.com/"
        }
    }
    ~링크 영역~
}

HATEOAS를 사용하여 얻게 되는 가장 큰 장점은 서버와 클라이언트를 분리한다는 것이다.
클라이언트는 서버의 상태와 행동을 알 필요가 없으며, 서버 측의 변경에도 클라이언트에선 일일이 대응하지 않아도 된다.
 

마무리

이로써 우리는 HATEOAS로 보다 RESTful 한 API를 작성하는 방법을 배웠다.
하지만 모든 공공기관 또는 기업에서 사용하지 않는 것처럼 반드시 HATEOAS를 사용해야 하는 것은 아니다.
적재적소에 맞는 REST API를 설계하여 사용하는 게 더욱 중요하며, HATEOAS는 필요에 따라 적절히 사용하도록 하자.
 
참고
https://wonit.tistory.com/454
https://grapeup.com/blog/how-to-build-hypermedia-api-with-spring-hateoas/#

반응형

블로그의 정보

슬기로운 개발생활

coco3o

활동하기