API 란?
- Application Programming Interface
- API는 프로그램들이 서로 상호작용하는 것을 도와주는 매개체로 볼 수 있다.
- API의 역할
- API는 서버와 데이터베이스에 대한 출입구 역할을 한다.
- API는 애플리케이션과 기기가 원활하게 통신할 수 있도록 한다.
- API는 모든 접속을 표준화한다.
REST 란?
- REpresentational State Transfer
- 컴퓨터 시스템와 인터넷 사이에 상호 운용성을 제공하는 방법중 하나이다.
- 시스템 제각각의 독립적인 진화를 보장하기 위한 방법이다.
- REST API: REST 아키텍처 스타일을 따르는 API 를 뜻한다.
REST를 구성하는 스타일
- Client-Server : 클라이언트 - 서버 구조를 이루어야 한다.
- Stateless : 상태가 유지되어선 안되고, 단순히 데이터를 주고받는 것으로 끝나야한다.
- Cache : 클라이언트는 응답을 캐싱할 수 있어야 한다.
- Uniform Interface : 아래에서 자세히 설명하겠다.
- Layered System : 계층형 구조가 되어야 한다.
- Code-on-Demand (optional) : 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 한다
- REST API 라고 부르는 API 들은 대체로 위의 조건을 거의 만족하고 있다.
- 그 이유는 HTTP만 잘 따라도
Client-Server, Stateless, Cache, Layered System
은 다 지킬 수 있기 때문이다. - Code-on-Demand는 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 한다는 것을 의미, 즉 자바스크립트를 의미하고 이는
필수는 아니다.
- 그렇다면 로이 필딩는 왜 대부분의 REST API 라고 주장하는 API 들이 REST 스럽지 못하다고 했을까?
- 그 이유는
Uniform Interface
를 만족하지 못하는 것이 대부분이다.
- 그 이유는
- 그 이유는 HTTP만 잘 따라도
Uniform Interface 제약 조건
- Identification of resources
- URI로 리소스가 식별되면 된다는 것
- Manipulation of resources through representations
- Manipulation of resources through representations는 representation 전송을 통해서 리소스를 조작해야된댜는 것
- Self-descriptive messages
- 메시지는 스스로를 설명해야한다.
- Hypermedia as the engine of application state(HATEOAS)
- 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.
- 여기서 Identification of resources, Manipulation of resources through representations 의 조건이 갖는 의미는 리소스를 만들거나 삭제, 수정할 때 http 메시지에 그 표현을 전송해야된다는 것이다. 이 2가지 조건은 대부분 잘 지켜지고 있다.
- 하지만
Self-descriptive messages, ypermedia as the engine of application state
는 사실 우리가 REST API라고 부르는 거의 모든 것들은 지키지 못하고 있다.
Self-descriptive messages
메시지 스스로 메시지에 대한 설명이 가능해야 한다.
- 서버가 변해서 메시지가 변해도 클라이언트는 그 메시지를 보고 해석이 가능하다.
- 확장 가능한 커뮤니케이션을 말한다.
- 미디어 타입을 정의하고 IANA에 등록하고 그 미디어 타입을 리소스 리턴할 때 Content-Type으로 사용하면 해결할 수 있다.
- 예시
- Self-descriptive messages를 만족하지 못한 예시
GET / HTTp/1.1
- 목적지가 빠져있다.
HTTP/1.1 200 OK [ { "op": "remove", "path": "/a/b/c" } ]
- 클라이언트가 해석하지 못한다.
- 목적지가 빠져있다.
- Self-descriptive messages를 만족한 예시
GET / HTTp/1.1 Host: www.example.org
- 목적지를 정의했기에 만족한다.
HTTP/1.1 200 OK Content-Type: application/json-patch+json [ { "op": "remove", "path": "/a/b/c" } ]
- json-patch+json이라는 미디어 타입으로 정의된 메시지이기 때문에 json-patch라는 명세를 찾아가서 이해한 다음, 이 메시지를 해석을 하면 그제서야 올바르게 메시지의 의미를 이해할 수 있게 된다.
- 목적지를 정의했기에 만족한다.
- Self-descriptive messages를 만족하지 못한 예시
- profile 링크 헤더를 추가하는 방법으로 아래와 같이 해결할 수도 있다.
- 이제 메시지를 보는 사람은 명세를 찾아갈 수 있음 → 의미 해석 가능
GET /todos HTTP/1.1 Host: example.org HTTP/1.1 200 OK Content-Type: application/json Link: <https://exmaple.org/docs/todos>; rel="profile" [ {"id": 1, "title": "회사 가기"}, {"id": 2, "title": "집에 가기"} ]
Hypermedia as the engine of application state(HATEOAS)
하이퍼미디어(링크)를 통해 애플리케이션 상태 변화가 가능
해야 한다.- 링크 정보를 동적으로 바꿀 수 있다.
- 즉, 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.
- 상태는 아래와 같이 변할 수 있다.
루트 홈페이지 → 글 목록 보기 GET → 글 쓰기 GET → 글 저장 POST → 생성된 글 보기 GET → 목록 보기 GET →
- 이렇게 상태를 전이하는 것을 애플리케이션 상태 전이라고 하고, 이 상태 전이마다 항상 해당 페이지에 있던 링크를 따라가면서 전이했기 때문에 HATEOAS라고 할 수 있다.
- 그렇다면 왜 REST 가 지켜지기 어려운가?
- 위에서 보듯 의미를 해석하기 위해서는 별도의 문서가 필요하다.
HTTP/1.1 200 OK Content-Type: text/html
``` - a 태그를 통해서 하이퍼링크가 나와 있고, 이 하이퍼 링크를 통해서 그 다음 상태로 전이가 가능하기 때문에 만족한다고 볼 수 있다.
- Json으로 표현하면 아래와 같다.
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..."
}
- Link라는 헤더가 있는데, 이것이 바로 이 리소스와 하이퍼링크로 연결되어 있는 다른 리소스를 가르킬 수 있는 기능을 제공해준다.
- 여기서 어떤 1개의 게시물을 표현 했는데, 이전의 게시물 URI가 /articles/1, 다음 게시물은 /articles/3에 있다는 정보를 표현해준 것이다.
- 이 정보는 Link 헤더가 이미 표준으로 문서가 나와 있기 때문에 이 메시지를 보낸 사람이 온전히 해석해서 어떻게 링크가 되어 있는가를 이해하고 하이퍼링크를 타고 다른 상태로 전이가 가능하다.
- 또한 아래와 같이 JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용해서 해결할 수 있다.
```java
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
Link: <https://exmaple.org/docs/todos>; rel="profile"
{
"data": [{
"type": "todo",
"id": 1,
"attributes": {"title": "회사 가기"},
"links" : { "self": "https://example.org/todos/1"
},{
"type": "todo",
"id": 2,
"attributes": {"title": "집에 가기"},
"links" : { "self": "https://example.org/todos/2"
}]
}
정리
- 오늘날 대부분 "REST API"는 사실 REST를 따르고 있지 않다.
- REST의 제약 조건 중 특히
self-descriptive와 HATEOAS를 잘 만족하지 못한다
. - REST를 따를 것인지는 API 설계하는 이들이 스스로 판단하여 결정하면 되지만, REST의 조건을 전부 만족시킬 수 없다면
REST API라 부를 수 없다.
REFERENCES
- 백기선님의 스프링 기반 REST API 개발
- 네이버 컨퍼런스 : https://www.youtube.com/watch?v=RP_f5dMoHFc
- https://ozofweird.tistory.com/entry/RESTful-API-%EA%B7%B8%EB%9F%B0-REST-API%EB%A1%9C-%EA%B4%9C%EC%B0%AE%EC%9D%80%EA%B0%80#recentEntries
- https://velog.io/@kjh03160/%EA%B7%B8%EB%9F%B0-REST-API%EB%A1%9C-%EA%B4%9C%EC%B0%AE%EC%9D%80%EA%B0%80
'Network' 카테고리의 다른 글
쿠키와 캐시 (0) | 2022.02.27 |
---|---|
네트워크 (0) | 2022.02.27 |
URI 설계 원칙(RFC-3986) (0) | 2022.02.27 |
HTTP (0) | 2022.02.27 |