본문 바로가기
프로그래밍/기타

[REST API] HATEOAS(Hypermedia as the Engine of Application State)

by 사바라다 2019. 10. 13.

오늘의 주제는 HATEOAS입니다. HATEOAS는 Hypermeia as the Engine of Applicaation State의 약자로 REST에서 리소스의 3가지 요소(Data, Meta Data, HATEOAS)중 하나입니다.

개요

HATEOAS는 REST 어플리케이션이 다른 아키텍처와 다른 부분 하나입니다. 다른 아키텍처들에서 Hypermedia는 이미지, 동영상 등을 참조할 때 사용합니다. 하지만 REST는 본인의 모든 Resource의 요청을 HATEOAS를 통해 진행합니다.

예를 들어 게시판을 운영하고 있다고 합시다. 그리고 요청으로 모든 게시판의 리스트를 가져오겠다. 라고 한다면 아래와 같은 요청을 보낼 수 있을 것입니다.

HTTP GET http://sabarada.tistory.com/boards

위 요청에 대해서 응답을 줄때 REST는 각 리소스의 link를 함께 줍니다. link를 함께 주기때문에 client는 자유롭게 서버와는 독립적으로 리소스를 요청하거나 할 수 있게됩니다.

아래는 응답 리소스의 위치를 body에 담아서 응답의 예시입니다.

{
    "boards" : [
        {
            "idx" : 1,
            "title" : "1 title",
            "contents" : "1 contents"
            "links" : [
                "href" : "boards/1",
                "rel" : "board"
            ]
        },
        {
            "idx" : 2,
            "title" : "2 title",
            "contents" : "2 contents"
            "links" : [
                "href" : "boards/2",
                "rel" : "board"
            ]
        }
        ...
    ]
}

다른 방법으로는 Link Header를 이용할 수 있습니다. link header를 이용하면 위의 예제는 아래 같이 바뀔것입니다.

HTTP/1.1 200 OK
...
Link: <boards/1>; rel="board"; idx=1
Link: <boards/2>; rel="board"; idx=2
{
    "boards" : [
        {
            "idx" : 1,
            "title" : "1 title",
            "contents" : "1 contents"
        },
        {
            "idx" : 2,
            "title" : "2 title",
            "contents" : "2 contents"
        }
        ...
    ]
}

위의 2개의 어떤 예제가 더 좋은 예제라는 것은 없습니다. 동일한 HATEOAS를 다르게 표현해 본것으로 본인의 상황에 따라서 사용하면 됩니다.

HATEOAS References

HATEOS의 format은 대표적으로 WebLink와 HAL 2가지를 사용합니다.

WebLink(RFC5988)

web link는 우리가 개요에서 봤던 방식으로 HATEOAS를 규정합니다.

일반적으로 아래의 3가지 요소를 포함합니다.

  • Target URI : 전이, 요청을 할 수 있는 link입니다. href라고 표현합니다.
  • Link Relation Type : target resource의 URI와 현재 URI가 어떻게 연결되어있는지 관계에 대해 정의 합니다. rel라고 표현합니다.
  • Attribute for target URI : target link를 부가 설명할 수 있는 요소입니다. title, media, type 및 정의에 따라 사용할 수 있습니다.

더 상세한 내용은 링크를 확인해주시기 바랍니다.

HAL(Hypermidea API Language)

HAL은 json또는 xml의 content에 link를 담는 방식을 사용합니다.

아래 2개의 contentType 사용하여 표현합니다.

  • media type: application/hal+xml
  • media type: application/hal+json

hal을 이용해서 개요의 예제를 한번 만들어 보겠습니다.

{
    "_links" : {
        "self" : {
            "href" : "/boards"
        }
    },
    "_embeded" : {
        "boards" : [{
            "idx" : 1,
            "title" : "1 title",
            "contents" : "1 contents"
            "_links" : {
                "self" : {
                    "href" : "/boards/1"
                }
            }
        },{
            "idx" : 2,
            "title" : "2 title",
            "contents" : "2 contents"
            "_links" : {
                "self" : {
                    "href" : "/boards/2"
                }
            }
        }]
    }

hal에 명시되어있는 예약어 등을 통해서 제작해 보았습니다.

간단히 예약어를 보자면

  • _link : 호출한 resource와 연관있는 link들을 collection의 형식으로 나타냅니다.
  • _embedded : 해당 resource가 포함하고 있는 요소를 나타냅니다.
  • self : 각 Resource에 대해서 본인의 Resource에 대한 link는 반드시 포함해아합니다.

더 상세한 내용은 링크를 확인해주시기 바랍니다.

참조

https://restfulapi.net/hateoas/

https://tools.ietf.org/html/rfc5988

https://tools.ietf.org/html/draft-kelly-json-hal-08

댓글