지인과 오랜만에 대화를 나누다가 최근 서버에 관심이 생겼다는 나의 말에 REST API도 공부해보면 어떻겠냐는 얘기를 꺼냈다. 처음에는 'REST API? API가 쉴 수도 있나?'라는 말도 안되는 생각회로를 돌렸다. 궁금한 건 못 참는 성격에 조금이라도 알아보자고 마음먹었지만, 개강하고 나서 개강 후 수강정정과 다시 돌아온 대면수업에 정신 못차리다가 이제서야 들춰보게 되었다.
REST API의 사전적 정의는 이러하다.
REpresentational State Transfer
a way of providing interoperability between computer systems on the Internet.
REST API는 REST 아키텍쳐 스타일을 따르는 API를 말한다.
REST는 분산 하이퍼미디어 시스템(예: 웹)을 위한 아키텍쳐 스타일이다.
아키텍쳐 스타일은 제약조건들의 집합이다.
REST를 구성하는 스타일
대체적으로 오늘날 REST API로 불리는 것들은 HTTP만 따라도 잘 지킬 수 있다. 그러나, uniform interface이라는 것이 잘 지켜지지 않는다. 이것도 스타일이기 때문에 4가지의 제약조건으로 이루어져 있다.
Uniform Interface의 제약조건
이 제약조건들 중에서 볼드체로 표현된 부분들이 문제를 가지고 있다. 거의 모든 오늘날 REST API라고 알려진 것들은 이 두가지를 지키지 못하고 있다고 한다.
메시지는 스스로를 설명해야 한다
Self-descriptive는 확장 가능한 커뮤니케이션을 가능하게 한다. 서버나 클라이언트가 변경되더라도 오고가는 메세지는 언제나 self-descriptive 하므로 언제나 해석이 가능하다.
GET/ HTTP/1.1
// 이 GET 메소드 요청 메세지는 뭔가 빠져 있어서 self-descriptive 하지 못하다.
---------------------------------------------------------------------
GET/ HTTP/1.1
Host: www.example.org
// 목적지를 추가해주어 이제 self-descriptive 하다고 볼 수 있다.
애플리케이션의 상태는 하이퍼링크를 이용하여 전이되어야한다
애플리케이션 상태 전이의 late binding이 가능하다. 어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정되는 것이다. 쉽게 말해서 링크는 동적으로 변경될 수 있다.
위 그림의 경우, 해당 페이지에 존재하는 링크를 따라가면서 전이되었기 때문에 HATEOAS가 되는 것이다.
독립적인 진화를 하기 위해서이다. 서버와 클라이언트가 각각 독립적으로 진화한다. 서버의 기능이 변경되어도 클라이언트는 업데이트할 필요가 없다. REST를 만들게 된 계기는 "How do I improve HTTP without breaking the Web?""이다. 즉, 'HTTP를 수정하게 되면 Web이 깨질 것 같은데 어떻게 하면 문제를 해결할 수 있을까?' 에 대한 고민의 해결책으로 나온 것이 REST이고, REST가 목적하는 바는 독립적인 진화이다. 따라서 독립적인 진화가 되기 위해서는 Uniform Interface를 지키지 못한다면 REST하지 못하다고 말할 수 있다.
웹 페이지를 변경했다고 웹 브라우저를 업데이트할 필요는 없다. 웹 브라우저를 업데이트했다고 해서 웹 페이지를 변경할 필요도 없다. HTTP 명세가 변경되어도, HTML 명세가 변경되어도 웹은 잘 동작한다.
HTTP에 지속적으로 영향을 주고, HOST 헤더추가, 길이 제한을 다루는 방법을 명시하고, URI에서 리소스의 정의가 "식별하고자 하는 무언가"로 추상적으로 변경되었다. 이외에도 기타 HTTP와 URI에 많은 영향을 주었다. 이렇게 웹은 독립적으로 진화하고 있고, 웹의 독립적 진화를 위해 만들어진 REST는 성공하였다고 말할 수 있겠다.
REST API는 REST 아키텍쳐 스타일을 따라야 한다. 오늘날 스스로 REST API라고 하는 API들의 대부분이 REST 아키텍쳐 스타일을 따르지 않는다. 그렇다면, REST API도 제약조건들을 다 지켜야 하는건가? 결과적으로 말하자면 지켜야한다고 한다.
"An API that provides network-based access to resources via an uniform interface or self-descriptive messages containing hypertext to indicate potential state transitions might be part of an overall system that is RESTful application -- Roy T.Fielding
자원의 표현을 가지고 상태를 전달한다
모든 URI는 자원으로 나타내야 한다. 그렇기에 URI에는 무조건적으로 동사가 아닌 명사가 들어가야한다. 그리고 모든 동작은 Method로 나타낸다. HTTP의 메소드에는 GET(조회),POST(생성), PUT(수정), DELETE(삭제) 등이 존재한다. 그리고 리소스의 응답 타입은 Header로 나타내주어야 한다.
REST API는 결국, Self-descriptive와 HATEOAS를 따르는 만족시키는 API이고, 간단하게 표현하자면 API를 통해서 어떤 요청인지 해석이 가능하고 하이퍼링크를 통해서 전이가 가능해야 한다는 것 같다. 이제와서 생각해보면 2월에 진행했던 로그인&회원가입 클론 코딩을 진행했을 때, URI에 GET과 POST를 사용하여 동작을 나타내고 URI에 명사를 사용한 점, a태그에 링크를 삽입하여 전이시키도록 한 점을 미루어 보았을 때, REST API를 구현했다고 볼 수 있겠다. 이렇게 또 하나 배움의 즐거움을 얻었다!
Day1, 2-2. 그런 REST API로 괜찮은가
[Restful API] 자원의 표현을 가지고 상태를 전달한다.