a way provide interoperability between computer systems on the Internet.
(컴퓨터 시스템간의 상호 운영성을 제공하는 방법 중 하나)
어떻게 인터넷에서 정보를 공유할 것인가?
HTML 형식으로 정보들을 표현하고 정보들의 식별자로 URI를 만들었고 그리고 그 정보들을 전송하는 방법으로 HTTP Protocol을 만들었다.
HTTP는 정보들을 전송하는 방식으로 HTTP/1.0 version이 나오기전에 이미 많은 사용자들이 WEB 전송 방식으로 급속도로 사용하고 있었습니다. 그러는 도중에 HTTP/1.0을 만들기 위해서 Roy T. Fielding이 제작에 참여하였습니다. 이 시점에서 HTTP를 정립하고 명세의 기능을 더하고 기존의 기능을 수정해야 하는 상황이 발생했습니다. 그러면 기존에 이미 구축된 WEB과 충돌하는 문제가 발생했습니다.
이전에 구축한 WEB을 망가트리지 않고 HTTP를 진보시킬 수 있는지 Roy T. Fielding은 고민을 했고 그 해결책으로 HTTP Object Model을 발표하게 되었습니다. 발표한 HTTP Object Model은 4년 후에 REST 논문을 Roy T. Fielding이 발표하면서 REST가 탄생하게 되었습니다.
위의 글을 정리해보면 Roy T. Fielding은 이전에 구축한 WEB에 영향을 미치지 않으면서 새롭게 구축한 HTTP/1.0 Protocol을 사용하는 방법을 만들기 위해서 REST를 만들게 되었다고 정리할 수 있습니다.
REST: Representational State Transfer
- Architectural Styles and the Design of Network-based Software Architectures
REST는 제약 조건의 집합을 의미하며 모든 제약조건을 지켜야 REST라고 지칭할 수 있는 점을 주의해야합니다. 그러기 위해서는 REST에서 사용하는 제약 조건에 대해서 알아보겠습니다.
대체로 REST API라고 불리는 API들은 어느정도의 REST를 잘 지키고 있습니다. 그 이유로는 우리가 정보 전송을 위해 사용하는 HTTP의 규칙만 잘 지켜도 Client - Server, Stateless, Cacheable, layered system와 같은 대부분의 REST Design Architecture을 지킬 수 있기 때문입니다. Code-on-demand 같은 경우는 optional로 serverd에서 코드를 Client 보내서 실행할 수 있어야 하며 가장 유명한 예시는 JavaScript를 server에서 Client로 보내는 방식입니다.
대부분의 REST 규칙은 HTTP의 규칙을 따른다고 해도 REST의 규칙 중 하나인 Uniform Interface는 외에는 전부 지킬 수 있습니다. 그렇다면 Uniform Interface를 지킬 수 있는 방법을 알아야 완벽한 REST API를 만들 수 있습니다.
Uniform Interface의 제약 조건 중에서도 identification of resources와 manipulation of resources through representations는 잘 지켜지고 있습니다.
URL로 통일해서 통신을 합니다.
http://localhost:8080/profile-photo
http://localhost:8080/location
자기 서술적 메시지라는 의미로 각 메시지는 자신을 어떻게 처리해야 하는지 충분한 정보를 HTTP Method, Status Code, Header 등을 활용하여 전달 해야합니다.
GET / HTTP/1.1
이 HTTP 요청 메시지는 목적지가 존제하지 않기때문에 self-descriptive가 아닙니다.
GET / HTTP/1.1
Host: www.example.org
목적지를 추가해서 self-descriptive 조건을 만족 시킬 수 있습니다.
HTTP/1.1 200 OK
[ { “op” : “remove”, “path” : “a/b/c"} ]
이 부분을 해석하기 위해서는 Client가 이 응답을 받고 해석해야 하지만 이 정보가 어떤 문법으로 작성된것인지 알 수 없기때문에 self-descriptive가 아닙니다.
HTTP/1.1 200 OK
Content-Type: application/json
[ { “op” : “remove”, “path” : “a/b/c"} ]
Content-Type에 어떻게 문법을 해석할것인지를 알려주면 대갈호의 의미, 중갈호의 의미, 큰 따옴표의 의미 등을 Client가 문법에 맞게 파싱이 가능해지고 문법을 해석할 수 있게 만들어 줍니다.
여기까지 작성하여도 self-descriptive의 조건을 만족하지 않습니다. 왜냐하면 op, path 와 같은 문자열로 보내는 데이터의 정확한 의미를 알 수 없기때문입니다.
HTTP/1.1 200 OK
Content-Type: application/json + patch+json
[ { “op” : “remove”, “path” : “a/b/c"} ]
patch+json은 media type으로 정의되어 있는 메시지로 JSON PATCH 명세를 찾아서 메시지를 해석할 수 있습니다. 이제는 self-descriptive 조건을 만족하고 있습니다.
self-descriptive messages는 메세지를 봤을때 메시지의 내용으로 온전히 모든 정보가 해석이 가능해야 하지만 대부분의 API가 이 부분을 상당히 만족하지 못하고 있습니다.
결국 HATEOAS의 목적은(서버-클라이언트 간 의존성을 분리해야만 가능한) 독자적인 진화와 확장을 보조하는 것이며, hypermedia는 그 목적을 이루는 데 기여해야 합니다.
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head></head>
<body>
<a href="/test">test</a>
</body>
</html>
server의 응답이 html 같은 경우는 <a> 태그를 통해서 hyperLink가 있고 hyperLink로 다음 상태로 전이가 가능해서 따로 설정을 하지 않아도 HATEOAS를 만족합니다.
HTTP/1.1 200 OK
Content-Type: application/json
Link: </articles/1>; rel=“previous”,
</articles/3>; rel=“next”;
{
“Title” : “The second article”,
“content” : “Hello! Brother"
}
JSON data 또한 Link 헤더를 사용하여 hyperLikn를 통해서 리스소와 연결되어 있는 다른 리소스를 가르킬 수 있는 기능을 제공해서 HATEOAS를 만족할 수 있습니다.
위의 http를 보면 게시글에 관련된 정보로 이전 게시물의 URI는 </articles/1>이고 다음 게시물의 URI는 </articles/3>라고 하는 정보를 표현해 주었습니다. 또한 이 정보는 Link 헤더가 http 표준으로 이미 정의되어 있기 때문에 이 메시지를 보는 사람이 온전히 해석해서 어떻게 링크가 되어 있는지가를 이해하고 hyperLink를 찾아 다른 상태로 전이를 할 수 있어서 위의 예제는 HATEOAS의 조건을 만족합니다.
REST가 목적하는 것은 독립적인 진화입니다. 독립적인 진화를 하기 위해서는 Uniform Interface가 반드시 만족되어야 합니다. 그렇기 때문에 Uniform Interface를 만족하지 못하면 REST라고 부를 수 없습니다.