Iyoungman Back-end Developer

REST API의 특징

2020-07-07

HTTP API에 REST 아키텍처를 적용한 목적

  • 시스템의 독립적인 진화를 보장하기 위해서이다.


REST 아키텍처 스타일

  1. Client-Server
  2. Stateless
  3. Cache
  4. Uniform Interface
  5. Layered System
  6. Code-On-Demand (optional)


  • HTTP API를 사용해도 대부분 지킬 수 있다.
  • 단, Uniform Interface는 제외.


Uniform Interface

  • HTTP 표준에만 따른다면 어떠한 기술이라던지 사용이 가능하며
    URI로 지정한 리소스에 대한 조작이 가능한 아키텍처 스타일을 의미한다.

  • 위의 개념이 대두된 배경은 크게 2가지가 있다.
  • [1] 애플리케이션의 복잡도가 증가하면서 애플리케이션의 분리 및 통합이 중요해졌다.
  • [2] 모바일과 같은 다양한 클라이언트 환경이 등장하면서 백엔드 하나로 다양한 Device에 대응하기 위함이다.


Uniform Interface 제약조건

  1. identification of resources
  2. manipulation of resources through represenations
  3. self-descrive messages
  4. hypermisa as the engine of appliaction state (HATEOAS)


  • 이중 REST API라고 불리는 대부분의 API는 2가지를 지키고 있지 않다.



Self-descriptive message

  • 메시지 스스로 메시지에 대한 설명이 가능해야 한다.
  • 서버의 내용이 변해서 메시지가 변해도 클라이언트는 그 메시지를 보고 해석이 가능하므로 확장 가능하다.

예제 1

HTTP/1.1 200 OK

[ {"op" : "remove", "path" : "a/b/c/"} ]
  • self-descriptive 하지 못하다.
  • 어떻게 해석해야할지 모르기 때문이다.


예제 2

HTTP/1.1 200 OK
Content-Type : application/json

[ {"op" : "remove", "path" : "a/b/c/"} ]
  • self-descriptive 하지 못하다.
  • Json Type이라는 것을 이해할 수 있기 때문에 파싱은 가능하다.
  • 하지만 ‘op’와 ‘path’ 의미를 알 수 없다.


예제 3

HTTP/1.1 200 OK
Content-Type: application/json-patch+json

[ { "op": "remove", "path": "/a/b/c" } ]
  • self-descriptive 하다.
  • json patch + json이라는 미디어 타입으로 정의되어 있다.
  • json patch 라는 명세를 찾아가면 메시지를 해석할 수 있다.



HATEOAS

  • 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.
  • 서버가 링크를 바꾼다고 해도 클라이언트는 바꾼 링크를 확인할 수 있다.


image


예제 1

HTTP/1.1 200 OK
Content-Type : text/html

<html>
    <head></head>
    <body><a href="/test">test</a></body>
</html>
  • HATEOAS를 만족한다.
  • a link로 연결되어 있기 때문이다.


예제 2

HTTP/1.1 200 OK
Content-Type : application.json
Link : </articles/1>; rel="previous",
       </articles/3>; rel="next";
{
    "title" : "The second article",
    "contents" : "blah blah ..."
}
  • HATEOAS를 만족한다.
  • Link 라는 헤더를 통해 이 리소스가 연결되어 있는 다른 리소스를 제공하기 때문이다.


Self-descriptive message 지키기

[방법 1] Media type

  • 미디어 타입을 정의하여 IANA에 등록한다.
  • 리소스를 리턴할 때 정의한 미디어 타입을 Content-Type으로 사용한다.
GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/vnd.todos+json

[
  {"id": 1, "title": "회사 가기"},
  {"id": 2, "title": "집에 가기"}
]
  • 단점은 필요한 Media type을 직접 등록해야하므로 번거롭다.


[방법 2] Profile

  • 명세를 작성한다.
  • Link 헤더에 해당 명세를 링크한다.
GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://example.org/docs/todos>; rel="profile"

[
  {"id": 1, "title": "회사 가기"},
  {"id": 2, "title": "집에 가기"}
]


HATEOAS 지키기

[방법 1] 데이터에 링크 제공

GET /todos HTTP/1.1
Host: example.org


HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://example.org/docs/todos>; rel="profile"

{
  "links": {
    "todo": "https://example.org/todos/{id}"
  },
  "data": [{
    "id": 1,
    "title": "회사 가기"
  }, {
    "id": 2,
    "title": "집에 가기"
  }]
]


[방법 2] 링크 헤더나 Location 제공

POST /todos HTTP/1.1
Content-Type: application/json

{
    "title": "점심 약속"
}


HTTP/1.1 204 No Content
Location: /todos/1
Link: </todos/>; rel="collection"


Reference


Comments

Content