RESTful WEB API 3~4장을 읽으며 중요한 내용을 기록했습니다.
3장 리소스와 표현
URL, HTTP, HTML 이 세 가지 웹 기술 아래에는 리소스와 표현이라는 두 가지 필수적인 개념이 있다.
무엇이든 리소스가 될 수 있다
유일한 제약 조건이 있는데, 바로 모든 리소스는 URL을 가져야 한다는 것이다.
표현은 리소스 상태를 설명한다
클라이언트가 리소스에 GET 요청을 보내면 서버는 그 리소스를 유용한 방식으로 나타내는 문서를 제공해야 한다. 그게 바로 표현이다.
표현은 리소스에 대한 어떤 정보든 담을 수 있고, 기계가 읽을 수 있는 어떠한 문서이든 상관없다.
표현은 양방향으로 전송된다
서버는 리소스의 상태를 나타내는 표현을 보낸다. 클라이언트는 그 리소스가 가졌으면 좋을 상태를 설명하는 표현을 보낸다. 이것을 표현의 상태 전송이라 부른다.
많은 표현이 있는 리소스
두 가지 전략이 존재한다. 첫 번쨰는 내용 협상(content negotiation)인데 클라이언트는 HTTP 헤더의 값을 기준으로 각 표현을 구분한다. 두 번째는 그 리소스의 각 표현마다 다른 URL을 부여하는 것이다.
HTTP의 프로토콜 의미 체계
RESTful 시스템에서 클라이언트와 서버는 다음과 같이 미리 정의된 프로토콜을 따라 메시지를 보내는 것으로 상호 작용한다.
GET
클라이언트는 GET 요청을 보내 URL로 식별하는 리소스의 표현을 받아온다.
리소스 상태는 GET 요청을 서버로 보내거나 보내지 않거나 전혀 영향이 없어야 한다. 부수적으로 로깅이나 레이트 제한 등은 괜찮지만 클라이언트가 GET 요청으로 리소스 상태를 바꿀 것을 예상해서는 안된다.
가장 흔한 응답은 200(OK)이다. 301(Moved Permanently)같은 리다이렉트 코드 역시 흔하다.
DELETE
제거하고 싶은 리소스가 있을 때 클라이언트는 DELETE 요청을 보낸다. 물론 서버가 원하지 않는다면 지울 필요가 없다.
멱등성(idempotence) : DELETE 요청을 두 번 보내도 한 번 보냈을 때와 마찬가지로 리소스 상태에 동일한 영향을 미친다. GET 요청도 마찬가지이다.
POST
클라이언트가 POST로 추가하기 요청을 보내면 생성하길 원하는 리소스의 표현을 요청의 엔티티 바디에 담아 보낸다.
POST로 추가하기 요청의 가장 흔한 응답은 201(Created)이다. 또 다른 흔한 응답은 202(Accepted)인데, 서버가 받은 표현으로 새 리소스를 만들 계획이나 아직은 만들지 않았음을 의미한다.
PUT
리소스 상태를 변경할 때 보내는 요청이다. 서버가 요청을 수락하기로 결정하면 클라이언트가 표현으로 전달한 것에 맞춰 리소스 상태를 변경하고, 200(OK)이나 204(No Content)를 보낸다.
PATCH
표현 전체를 PUT으로 보내는 대신 변경을 나타내는 특수한 ‘diff’ 표현을 만들고 서버에 PATCH 요청의 페이로드를 보낸다.
PATCH가 성공했을 때 받을 응답은, 서버가 업데이트된 리소스의 표현과 같은 데이터를 보내고 싶다면 200(OK)이며, 성공만 알리고 싶다면 204(No contents)이다.
LINK와 UNLINK
LINK와 UNLINK는 리소스 간 하이퍼미디어 링크를 관리한다.
HEAD
HEAD는 GET의 가벼운 버전이라고 생각하는 것이 좋다. 서버는 HEAD 요청을 GET 요청과 동일하게 처리하고 엔티티 바디는 빼고 HTTP 상태 코드와 헤더만 전송하게 되어 있다.
OPTIONS
OPTIONS는 HTTP의 기초 발견 기법이다. OPTIONS 요청의 응답은 HTTP Allow 헤더를 담고 있는데, 해당 리소스가 지원하는 HTTP 메서드를 나열한다.
오버로드한 POST
HTTP POST는 온갖 종류의 변화를 지시할 때 사용된다. PUT, DELETE, PATCH, LINK, UNLINK가 한데 모여있는 메서드인 것이다.
폼 전송의 결과와 같이 데이터 블록을 데이터 처리 프로세스에 제공한다.
4장 하이퍼미디어
- URL은 리소스를 식별한다.
- 클라이언트는 이런 URL에 HTTP 요청을 보낸다.
- 서버는 응답으로 표현을 보내고, 시간이 지나면서 클라이언트는 표현을 통해 리소스 상태의 그림을 그려나간다.
- 결과적으로 클라이언트는 서버에 PUT, POST, PATCH 요청으로 표현을 전송해 해당 리소스 상태를 변경한다.
하이퍼미디어는 리소스를 서로 연결하며, 기계가 이해할 수 있는 방식으로 지원 가능 기능을 설명한다. 하이퍼미디어를 제대로 사용하면 오늘날 웹 API가 가지고 있는 사용성 및 안정성 문제를 해결하거나 적어도 완화할 수 있다.
하이퍼미디어 유형으로서의 HTML
하이퍼미디어는 애플리케이션 컨트롤 정보가 정보 표현 내부에 포함되거나 그 위 계층에 존재하는 것으로 정의한다.
URI 템플릿
URI 템플릿과 HTML 폼은 웹 서버가 무한한 수의 URL을 짧은 문자열로 설명할 수 있게 해준다. HTTP 클라이언트는 특정 값을 집어넣거나, 이 무한한 URL 중에서 하나를 고르고, 그 특정 URL에 GET 요청을 보낼 수 있다.
URI 대 URL
URL은 리소스를 식별하는 짧은 문자열이다. URI 역시 리소스를 식별하는 짧은 문자열이다. 모든 URL은 URI이다.
URI에는 표현이 있다는 보장이 없다는 것이 차이점이다. URI는 식별자일 뿐이다.
URL은 주소의 디레퍼런싱이 가능한 식별자다.
Link 헤더
RFC 5988은 HTTP의 확장을 정의하는데 Link라는 헤더다. 이 헤더는 JSON 객체나 바이너리 이미지 파일 같이 보통 하이퍼미디어를 지원하지 않는 엔티티 바디에 간단한 하이퍼미디어 컨트롤을 추가할 수 있게 해준다.
하이퍼미디어는 무엇을 위한 것인가
하이퍼미디어 컨트럴은 세 가지 역할을 수행한다.
- HTTP요청을 구성하는 방법을 클라이언트에 알려준다. 어떤 HTTP메서드를 사용할지, 어떤 URL을 사용할지, 어느 HTTP 헤더와 엔티티 바디를 보낼지를 알려준다.
- HTTP 응답에 대한 약속을 한다. 상태 코드, HTTP 헤더, 서버가 요청에 응답으로 보낼 데이터 등을 제시한다.
- 클라이언트가 자신의 작업 흐름에 응답을 어떻게 통합해야 할지 제시한다.
요청 안내하기
HTTP 요청은 메서드, 목적지 URL, HTTP 헤더, 엔티티 바디의 네 부분으로 이뤄진다. 하이퍼미디어 컨트롤은 클라이언트가 이 네 가지 모두를 지정하도록 안내한다.
하이퍼미디어 컨트롤은 HTTP 요청을 매우 상세하게 설명할 수 있다. 클라이언트에게 HTTP 요청을 특정 URL로 보내거나, 특정 HTTP 메서드를 사용하게 하거나, 특정 규칙에 따라 엔티티 바디를 구성하게 하거나 특정 HTTP 헤더에 특정 값을 제공하도록 할 수 있다.
응답에 대한 약속
1 | <link rel="edit" href="http://example.org/posts/1"> |
AtomPub 표준에 따라 rel=”edit”을 해석하면 http://example.org/posts/1에 있는 리소스에 대한 굉장히 많은 정보를 얻을 수 있다.
- 먼저, URL의 리소스가 GET뿐 아니라 PUT과 DELETE도 지원함을 알려준다.
- URL에 GET요청을 보냈을 때 어떤 종류의 응답을 얻게 될지 클라이언트가 추측할 필요를 없애준다는 것이다. AtomPub이 멤버 엔트리(Member Entry)라 부르는 종류의 문서를 응답으로 받게 된다.
작업 흐름 조절
하이퍼미디어의 세 번째 역할은 리소스 간의 관계를 설명하는 것이다.
가짜 하이퍼미디어를 조심하자!
1 | HTTP/1.1 200 OK |
1 | { |
application/json 미디어 유형은 하이퍼미디어 컨트롤을 전혀 정의하고 있지 않으므로 표현 일부가 하이퍼미디어 링크 같아 보이더라도 아니다. 그저 문자열일 뿐이다!
만일 이런 API를 소비하려 한다면, API 제공자가 작성한, 사람이 읽을 수 있는 문서를 읽게 된다. 그 문서는 API 제공자가 하이퍼미디어를 지원하지 않는 형식(JSON)안에 하이퍼미디어 링크를 포함시킬 때 사용하는 나름의 규칙을 설명할 것이다.
하지만 이렇게 작성한 클라이언트는 이 특정 API에만 동작할 것이다. 읽은 문서는 그저 하나의 명목 표준을 위한 문서인 것이다. 다음에 사용할 API는 JSON에서 하이퍼미디어 링크를 포함시킬 때 사용하는 또 다른 종류의 규칙을 가질 것이고, 이를 지원하려면 다시 작업해야 할 것이다.
그런 이유로 API 설계자들이 일반 JSON을 제공하는 API를 설계해서는 안 된다. 하이퍼미디어를 제대로 지원하는 미디어 유형을 사용해야 한다. 작성중인 API만을 위해 새로 만든 라이브러리 대신, 해당 미디어 유형을 지원하는 기존 라이브러리를 사용해야 한다.
JSON은 최근 수년간 API를 위한 가장 인기 있는 표현 형식의 자리를 차지하고 있는데, 하지만 얼마 전만 해도 JSON 기반 하이퍼미디어 유형을 존재하지 않았다. 다음 몇 장에 걸쳐서 볼 테지만 이제는 그렇지 않다. 진정한 하이퍼미디어를 얻기 위해 JSON을 포기해야 할 필요가 없어졌다.
