[REST API] ‘그런 REST API로 괜찮은가’를 보고나서 정리
처음 REST API 라는 개념을 접했을 때는 REST API가 무엇인지 잘 와닿지 않았다.
나중에 django rest framework를 사용해서 HTTP 메소드별 API를 만들고 postman으로 API 테스트를 하다보니 ‘아 이런게 REST API 구나’하고 경험적으로 조금씩 이해되기 시작했다.
이후 REST에 대해 더 자세히 이해하기 위해 해당 영상을 보게 되었다.
요약
REST는 REpresentational State Transfer의 약자로, 컴퓨터 시스템 간 상호 운용성을 제공하는 방법 중 하나임.(??)
REST 등장의 역사를 살펴보면
WEB(1991)이 처음 나왔을 때 정보 공유 방법으로 하이퍼텍스트를 사용하여 정보들을 전달하도록 다음과 같이 결정되었다.
- 정보 표현 형식: HTML
- 정보들의 식별자: URI
- 전송 방법: HTTP
HTTP 설계에 참여했던 로이 필딩이라는 사람은 기존에 구축된 웹과의 호환성을 해치지 않고 HTTP를 개선할 방법을 고민했고, 해결책을 논문으로 발표(2000) (여기서 REST의 정의가 등장)
이후 REST는 당시 존재하던 SOAP API보다 단순하고, 규칙이 적고 쉽다는 장점으로 인해 널리 쓰이게 되었다.
하지만 로이필딩이 생각한 REST와 사람들의 흔히 쓰는 REST 사이에는 미스매치가 존재했다.
Microsoft에서 2016년 REST API Guidelines를 발표했는데, 그 내용은 다음 내용 등이 포함되어있었다.
- uri는 https://{servieRoot}/{collection}/{id} 형식이어야 한다.
- GET, PUT, DELETE, POST, HEAD, PATCH, OPTIONS를 지원해야 한다.
하지만 로이 필딩은 위 내용은 REST API가 아니라고 주장했다.
로이 필딩의 REST API를 자세히 살펴보면
REST API는 REST 아키텍쳐 스타일을 따르는 API이며, 분산 하이퍼미디어 시스템(ex. 웹)을 위한 아키텍쳐 스타일이라고 한다.
여기서 아키텍쳐 스타일은 제약 조건의 집합이다.
REST의 아키텍쳐 스타일은 다음 6가지와 같다.
- client-server: 클라이언트가 요청(request)을 보내면 서버는 응답(response)을 돌려준다.
- stateless: http의 비연결성(connectionless)로 인해 서버는 클라이언트를 식별할 수 없는 것, 서버는 클라이언트의 어떠한 status도 저장하지 않음
- cache: 클라이언트는 응답을 캐싱할 수 있어야 함
- uniform interface
- layered system: 계층형 시스템 구조가 되어야함
- code-on-demand(optional): 서버에서 코드를 클라이언트에 넘겨서 실행할 수 있어야 한다. ( ex 자바스크립트)
위 제약 조건은 대체로 HTTP만 잘 따르면 지켜지게 된다.
하지만 이중 uniform interface는 만족하기 어렵다.
uniform interface는 4가지 제약 조건으로 이루어져 있다.
- identification of resources: 리소스가 uri로 식별되어야 함
- manipulation of resources through representations: 리소스를 create, update, delete 할 때 HTTP 메시지에 그 표현을 담아 전달해야 한다.(HTTP method)
- self-descriptive messages
- hypermedia as the engine of application state(HATEOAS)
이중 아래 2가지 조건은 사실 오늘날 알려진 REST API에서 지키지 못하고 있다.
1. self-descriptive messages
메시지가 스스로를 설명해야 한다.
self-descriptive하지 못한 요청
위 요청은 self-descriptive하지 못한 요청이다. 그 이유는 목적지가 빠져있기 때문이다.self-descriptive한 요청
다음과 같이 목적지가 추가되면 self-descriptive한 요청이 된다.self-descriptive하지 못한 응답 (1)
클라이언트가 위 응답을 해석해야 하는데 어떤 문법으로 작성된 것인지 모르기 때문이다.
self-descriptive하지 못한 응답 (2)
content type 헤더가 포함되면 이제 응답이 json 타입임을 알게되고 파싱이 가능해진다. 하지만 여기서 op, path의 의미는 알 수 없다. (현재 대다수 REST API 형태)self-descriptive한 응답
다음과 같이 하면 미디어 타입이 json patch임을 알게 되고 클라이언트는
json patch 명세서를 찾아 메시지를 완전히 해석이 가능해진다.
하지만 오늘날의 REST API는 위 조건을 만족하지 못한다.
이를 만족하기 위해서는 다음과 같은 과정이 필요하다.(예시)
(1) 미디어 타입을 새로 정의한다.
(2) 미디어 타입 문서를 작성하고, 이 문서에 “email”, “name”, “phone”이 무엇인지 의미를 정의한다.
(3) IANA에 미디어 타입을 등록한다.(vnd.profile+json), 이 때 만든 문서를 미디어 타입의 명세로 등록한다.
IANA 링크: https://www.iana.org/assignments/media-types/media-types.xhtml
이외에 profile link relation(명세를 링크로 넣는 방식, 영상 참고)방법이 있다.
2. HATEOAS
애플리케이션의 상태는 Hyperlink를 이용하여 전이되어야 한다.
HTML의 경우 HATEOAS를 만족하게 되는데 a태그를 통해 하이퍼링크가 나오고
하이퍼링크를 타고 그다음 상태로 전이가 가능하기 때문이다.
json으로 HATEOAS를 만족하는 방법은 다음과 같다.
Link 헤더를 통해 현재 리소스와 하이퍼링크로 연결되어 있는 다른 리소스를 표현해준다.
이외 직접 데이터에 하이퍼링크를 표현하는 방식이 있다.(영상 참고)
이렇게 Uniform interface가 필요한 이유는 다음과 같다.
"독립적 진화"를 위해서
- 서버와 클라이언트가 각각 독립적으로 진화한다.
- 서버의 기능이 변경되어도 클라이언트를 업데이트할 필요가 없다.
- REST를 만들게 된 계기: “How do I improve HTTP without breaking the Web.”
self-descriptive는 서버나 클라이언트가 변경되더라도 오고가는 메시지는 언제나 self-descriptive하기 때문에 언제나 해석이 가능하다.
HATEOAS는 애플리케이션 상태 전이의 late binding 이 가능하다 → 링크는 동적으로 상태 변경이 가능하다.(미리 결정되지 X)
현재의 web은 독립적 진화가 잘 이루어지고 있다.
- 웹 페이지를 변경했다고 웹 브라우저를 업데이트할 필요는 없다.
- 웹 브라우저를 업데이트했다고 웹 페이지를 변경할 필요는 없다.
- HTTP 명세가 변경되어도 웹은 잘 동작한다.
- HTML 명세가 변경되어도 웹은 잘 동작한다.
그렇다면 REST가 웹의 독립적 진화에 실질적 도움을 주었는가?
→ HTTP에 지속적으로 영향을 줌
- Host 헤더 추가
- 길이 제한을 다루는 방법 명시
- URI에서 리소스의 정의가 추상적으로 변경됨: “식별하고자 하는 무언가”
( -> 이전에는 “문서의 위치"로 정의 되어 있었음 )- 기타 HTTP, URI에 많은 영향을 줌
- HTTP/1.1 명세 최신판에 REST에 대한 언급이 많이 들어감
그럼 REST는 성공했는가? → 그렇다
- REST는 웹의 독립적 진화를 위해 만들어짐
- 웹은 독립적으로 진화하고 있다.
그런데 REST API는?
- REST API는 REST 아키텍쳐 스타일을 따라야 한다.
- 하지만 오늘날 스스로 REST API라고 하는 API들의 대부분이 REST 아키텍쳐 스타일을 따르지 않는다.
로이 필딩은 REST API는 REST 제약 조건을 모두 따라야 한다고 주장했다.
하지만 이렇게도 주장했다.
시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지 마라
- 시스템 전체를 통제할 수 있다. → 클라이언트와 서버를 모두 컨트롤할 수 있다.
- 진화에 관심이 없다. → 서버의 기능 변경에 따른 호환성 문제로 클라이언트 변경이 필요해도 상관 없다.(독립적 진화 x)
결론
-
현재의 상태는 엄밀하게 따져 REST API가 아니지만 REST API라고 부르는 상태
[비교]
웹 페이지 HTTP API Protocol HTTP HTTP 커뮤니케이션 사람-기계 기계-기계 Media Type HTML JSON Hyperlink 가능(a 태그) 정의되어있지 않음 self-descriptive 가능(HTML 명세) 불완전
-
REST 제약조건 중 self-descriptive와 HATEOAS를 잘 만족하지 못하고 따르기도 어렵다.
-
REST는 긴 시간에 걸쳐 진화하는 웹 애플리케이션을 위한 것이다.
-
REST를 따를 것인지는 API를 설계하는 이들이 스스로 판단하여 결정해야 한다.
-
정확한 REST를 따르겠다면 self-descriptive와 HATEOAS를 만족시켜야 한다.
-
정확한 REST API를 따르지 않겠다면 “REST API를 만족하지 않는 REST API”를 뭐라고 부를지 결정해야 한다.
- HTTP API라고 부를 수도 있고
- 그냥 이대로 REST API라고 부를 수도 있다.
생각
영상을 보고 초등학교 때 배운 편지 쓰는 방법이 생각났다.
그때 배웠던 편지 쓰는 방법은 먼저 받을 사람을 명시하고, 인사와 내용을 적은 뒤 마지막으로 쓴 날짜와 편지를 쓴 사람을 적는 방식이다.
하지만 실제로는 편지를 쓴 날짜가 빠지더라도 큰 문제가 되지 않으며, 마지막에 OO올림처럼 보내는 사람을 적지 않아도 받는 사람이 내용을 통해 보내는 사람을 알 수 있다면 편지에 문제가 생기지 않는다.
REST API의 현 상황이 이와 유사하다는 생각이 들었다. 원칙적으로 self-descriptive 조건이 완벽하게 충족하지 않아도 개발자들끼리 해당 내용들을 이해하고 있다면 데이터를 해석과 사용에 문제가 되지 않을 것이고, 프론트에서도 적절하게 데이터 배치가 가능할 것이다. HATEOAS 역시 충족되지 않더라도 다른 방식으로 URL들이 공유된다면 큰 문제가 되지 않을까라는 생각이 들었다.
추상적이고 어려운 내용이었지만 REST에 대해 더 자세히 알 수 있었고 앞으로 REST API에 대해 계속 고민이 필요하겠다는 생각이 들었다.
출처: https://www.youtube.com/watch?v=RP_f5dMoHFc
Author And Source
이 문제에 관하여([REST API] ‘그런 REST API로 괜찮은가’를 보고나서 정리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dhleeone/그런-REST-API로-괜찮은가를-보고나서-정리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)