REST 란?
REST
는 웹을 위한 아키텍쳐 스타일 이다.
아키텍쳐 스타일 : 제약조건의 집합
그래서 제약조건을 모두 만족해야 REST
라 할 수 있다.
REST 의 제약조건
- Client -server
- 서버와 클라이언트를 가져야 한다.- Stateless
- 상태를 가지면 안된다.- Cacheable
- 캐시를 가져야 한다.- Layerd system
- 레이어드 시스템 이어야 한다.- code-on-demand (optional)
- 서버에서 코드를 클라이언트에게보내서 실행 가능해야한다. (js)
위의 조건들은 HTTP 통신을 이용하면 자동으로 만족한다.
- uniform interface
- identifcation of resources
- manipulation of resources through representations
- self-descriptive messages
- hypermedia as the engine of application state (HATEOAS)
하지만 Uniform Interface
은 만족하는 것도 있고 만족 하지 않는 것도 있다.
Uniform Interface
HTTP 통신을 하면 만족하는 것
-
Identifcation of resources
- 자원으로 식별 할 수 있어야한다.
- URI 를 통한 식별
-
Manipulation of resources through representations
- 표현을 통해 자원을 조작 할 수 있어야 한다.
- HTTP 메소드를 통해 자원 조작 (CRUD 가능)
만족하지 않는 것 추가 구현을 통해 만족 시켜야 한다.
-
Self-descriptive messages
- 메시지가 스스로를 설명 해야한다.
- 목적지가 있아여 한다.
-
Hypermedia as the engine of application state (HATEOAS)
- 애플리케이션의 상태가 Hyperlink 를 통해서 전송되어야한다.
- 다음 상태를 링크로 표시해야한다.
웹을 사용하면 만족한다. 하지만 REST API
는 만족하지 않는다.
이유는 우리가 말하는 REST API
들은 대부분 Json
으로 데이터를 전송한다.
웹과 api 차이
웹은 REST
를 잘 만족하고 지킨다.
하지만 API
는 그렇지 못하다 왤까????
미디어 타입때문이다.
html : 하이퍼링크됨, 셀프 디스크립트 됨
json : 하이퍼링크 안됨, 셀프 디스크립트 불완전 (문법같은 것은 정의 값이 어떤값인지는 정의가 안되있다.)
따라서 api 문서를 만들고 json 요청에도 링크를 통한 추가 구현을 해야 한다.
REST API 는 REST 를 다 지켜야 하는가?
로이필딩은 그렇다고 한다. 셀프디스크립트와 헤이티오스를 지켜야 한다고 말한다.
지켜야 하는 이유
서버와 클라이언트는 독립적 진화를 해야한다. 서버의 기능이 변경되어도 클라이언트를 업데이트 할 필요가 없다.
현재상태
REST API
가 아니지만REST API
라 부른다. 어느정도는REST
를 만족하지만 완벽히 만족한다고 할 순 없다.
Self - descriptive 와 HATEOAS 가 독립적 진화에 도움이 될까?
서버가 어떻게 변하든 메세지만 갖고 해석이 가능해서 상관이 없어진다. 서버가 링크를 바꿔도 클라이언트의 동작엔 아무 문제가 없다.
만족시키려면
Self - descriptive
IANA에 미디어 타입을 등록한다. 이 때 만든 문서를 미디어 타입의 명세로 등록한다.
- ex) Content-Type: application/vnd.todos+json
단점
- 매번 media type을 정의해야한다
Link 헤더에 profile relation으로 해당 명세를 링크한다.
- ex) Link: https://example.org/docs/todos; rel="profile"
단점
- 클라이언트가 Link 헤더(RFC 5988)와 profile(RFC 6906)을 이해해야한다.
- Content negotiation을 할 수 없다
HATEOAS
- data 에 링크를 주어 표현한다.
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"
[
{
"link": "https://example.org/todos/1",
"title": "회사 가기"
},
{
"link": "https://example.org/todos/2",
"title": "집에 가기"
}
]
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": "집에 가기"
}]
}
단점 : 링크를 표현하는 방법을 직접 정의 해야한다.
- HTTP 헤더에 표현한다.
POST /todos HTTP/1.1
Content-Type: application/json
{
"title": "점심 약속"
}
HTTP/1.1 204 No Content
Location: /todos/1
Link: </todos/>; rel="collection"
단점: 정의된 relation만 활용한다면 표현에 한계가 있다.
정리
오늘날 REST API
는 사실 REST
를 따르지 않고 있다.
개발자가 상황에 맞게 REST
따를지 말지 스스로 판단하자.
만족시키려면 Self-descriptive 와 HATEOAS 를 만족 시키면된다.
따르지 않겠다면 http api
라 부르던가 그냥 rest api
라 부르자.
현재는 완벽히 만족하지 않지만 REST API
라고 부르고 있다.
참조
https://www.youtube.com/watch?v=RP_f5dMoHFc