HATEOAS (Hypermedia As The Engine Of Application State)
서버가 클라이언트에게 하이퍼 미디어를 통해 정보를 동적으로 제공해주는 것을 말한다.
RESTful API 설계의 중요한 개념으로, 클라이언트와 서버 간의 동적이고 유연한 상호작용을 가능하게 하는 방식.
하이퍼미디어를 애플리케이션의 상태를 관리하기 위한 메커니즘으로 사용한다. 이는 클라이언트가 서버와 동적으로 상호작용할 수 있도록 하며, API 응답에 관련 리소스에 대한 링크를 포함시키는 방식으로 구현된다.
전통적인 API와 HATEOAS API의 차이점
기존 API:
HATEOAS API:
HATEOAS의 작동 방식
- 서버는 클라이언트의 요청에 대한 응답으로 데이터와 함께 관련된 작업에 대한 링크를 제공한다.
- 클라이언트는 이러한 링크를 통해 다음에 수행할 수 있는 작업을 동적으로 파악할 수 있다.
- 이를 통해 클라이언트는 API의 구조에 대한 사전 지식 없이도 서버와 상호작용할 수 있다.
HATEOAS 구현 방법
대표적인 HATEOAS 표현 형식:
HAL (Hypertext Application Language): JSON이나 XML에서 하이퍼링크를 표현하기 위한 간단한 형식.
주요 특징:- 리소스와 링크 두 가지 개념으로 구성
_links
속성을 사용하여 관련 리소스 링크 제공_embedded
속성으로 관련 리소스 포함 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{ "_links": { "self": { "href": "/orders/523" }, "warehouse": { "href": "/warehouse/56" }, "invoice": { "href": "/invoices/873" } }, "_embedded": { "items": [ { "_links": { "self": { "href": "/items/1" } }, "name": "Widget", "price": 9.99 } ] }, "total": 30.00, "currency": "USD", "status": "shipped" }
JSON-LD (JSON for Linking Data): JSON-LD는 링크드 데이터를 JSON으로 인코딩하는 방법.
주요 특징:@context
를 사용하여 용어 정의@id
로 리소스 식별@type
으로 리소스 유형 지정
Siren: 엔티티를 표현하기 위한 하이퍼미디어 명세.
주요 특징:- 엔티티, 액션, 링크 구조 제공
class
속성으로 의미론적 분류 지원actions
속성으로 상태 전이 정의
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
{ "class": [ "order" ], "properties": { "orderNumber": 42, "itemCount": 3, "status": "pending" }, "entities": [ { "class": [ "items", "collection" ], "rel": [ "http://x.io/rels/order-items" ], "href": "http://api.x.io/orders/42/items" } ], "actions": [ { "name": "add-item", "title": "Add Item", "method": "POST", "href": "http://api.x.io/orders/42/items", "type": "application/x-www-form-urlencoded", "fields": [ { "name": "orderNumber", "type": "hidden", "value": "42" }, { "name": "productCode", "type": "text" }, { "name": "quantity", "type": "number" } ] } ], "links": [ { "rel": [ "self" ], "href": "http://api.x.io/orders/42" }, { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" }, { "rel": [ "next" ], "href": "http://api.x.io/orders/43" } ] }
Collection+JSON: Collection+JSON은 읽기/쓰기를 지원하는 JSON 기반 하이퍼미디어 타입.
주요 특징:- collection 객체 안에 여러 항목 포함
- queries와 template 제공
- items 배열에 데이터와 링크 포함
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
{ "collection": { "version": "1.0", "href": "http://example.org/friends/", "links": [ {"rel": "feed", "href": "http://example.org/friends/rss"} ], "items": [ { "href": "http://example.org/friends/jdoe", "data": [ {"name": "full-name", "value": "J. Doe"}, {"name": "email", "value": "jdoe@example.org"} ], "links": [ {"rel": "blog", "href": "http://examples.org/blogs/jdoe"} ] } ], "queries": [ {"rel": "search", "href": "http://example.org/friends/search", "prompt": "Search"} ], "template": { "data": [ {"name": "full-name", "value": ""}, {"name": "email", "value": ""}, {"name": "blog", "value": ""} ] } } }
HATEOAS의 주요 장점
클라이언트 독립성
- 서버가 제공하는 링크를 통해 클라이언트는 동적으로 다음 가능한 액션을 발견할 수 있다.
- 클라이언트 코드를 하드코딩된 URL에서 해방시켜 준다.
느슨한 결합
- 서버와 클라이언트 간의 강한 의존성을 줄인다.
- API 엔드포인트가 변경되어도 클라이언트 코드를 최소한으로 수정할 수 있다.
자가 설명적인 API
- 각 리소스는 그 자체로 어떤 작업을 수행할 수 있는지 설명한다.
- API 문서를 읽지 않아도 직관적으로 API를 탐색할 수 있다.
HATEOAS를 구현할 때의 고려사항
- 링크 관계
명명 표준 관계 타입(self, next, prev 등)을 사용하고, 커스텀 관계는 명확한 의미를 가지도록 정의한다. - 응답 크기
너무 많은 링크를 포함하면 응답 크기가 커질 수 있으므로, 실제로 필요한 링크만 포함하도록 한다. - 캐싱 전략
링크가 자주 변경되는 경우, 적절한 캐싱 전략을 수립해야 한다.
용어 정리
용어 | 설명 |
---|---|