공대생 정리노트

REST - Naver d2 그런 REST API로 괜찮은가 유튜브 요약 본문

로드맵/API

REST - Naver d2 그런 REST API로 괜찮은가 유튜브 요약

woojinger 2020. 8. 24. 22:34

참고자료

Naver d2. 그런 REST API로 괜찮은가

https://www.youtube.com/watch?v=RP_f5dMoHFc

 

Rest Dissertation

https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

 

Fielding Dissertation: CHAPTER 5: Representational State Transfer (REST)

proxy CERN Proxy, Netscape Proxy, Gauntlet

www.ics.uci.edu


REST

분산 하이퍼미디어 시스템(ex 웹)을 위한 아키텍쳐 스타일

 

REST를 구성하는 스타일은 다음과 같다.

  • client-server
  • stateless
  • cache
  • uniform interface
  • layered system
  • code-on-demand (optional) : 서버에서 클라이언트로 코드를 보내면 실행시킬 수 있어야 한다 ex) javascript

이미 존재하는 HTTP만 따라도 uniform interface를 제외한 스타일들을 다 지킬 수 있다.

 


Uniform Interface의 제약 조건

  • identification of resources : Resource가 URI로 식별되야 한다.
  • manipulation of resources through representations : representation 전송을 통해 resource를 조작해야 한다.
  • self-descriptive messages
  • hypermedia as the engine of application state (HATEOAS)

밑의 두 가지는 대부분의 REST API들이 지키지 못하고 있다.

 


Self-descriptive message

message만 보고서 무슨 뜻인지 알 수 있어야 함.

GET / HTTP/1.1

Self-descriptive하지 않다. 목적지가 빠져있음

GET / HTTP/1.1
Host: www.example.org

위와 같이 목적지를 추가하면 self-descriptive

 

HTTP/1.1 200 OK

[ { "op": "remove", "path": "/a/b/c" } ]

위와 같은 것도 self-descriptive하지 않다.

클라이언트가 위 응답을 받고 해석을 해야 하는데 어떤 문법으로 해석을 해야 하는지 모르기 때문에.

 

HTTP/1.1 200 OK
Content-Type: application/json

[ { "op": "remove", "path": "/a/b/c" } ]

따라서 Content-Type과 같은 Header가 있어야 문자열들의 의미를 알 수 있게 되고 parsing이 간으해짐.

하지만 parsing을 해도 "op"가 무엇인지, path가 무엇인지 알 수 없어 여전히 self-descriptive하지 않다.

 

HTTP/1.1 200 OK
Content-Type: application/json-patch+json

[ { "op": "remove", "path": "/a/b/c" } ]

json-patch라는 명세까지 써줘야지 올바르게 메세지를 이해할 수 있다.

 


HATEOAS

애플리케이션의 상태가 Hyperlink를 통해 전이되어야 한다.

 

HTTP/1.1 200 OK
Content-Type : text/html

<html>
<head></head>
<body><a href="/test">test</a></body>
</html>

위와 같은 코드는 하이퍼링크를 통하여 상태 전이가 가능하다. HATEOAS를 만족한다.

 

HTTP/1.1 200 OK
Content-Type: application/json
Link: </article/1>; rel="previous", </article/3>; rel="next";

{
	"title": "The second article",
	"contents": "blah"
}

 json도 Link라는 헤더를 통해 다른 리소스를 가리킬 수 있다.

Link 헤더가 표준으로 나와 있기 때문에 보는 사람이 해석을 할 수 있다.

 


왜 Uniform Interface를 해야 하는가?

서버와 클라이언트는 독립적으로 진화한다.

독립적 진화 : 서버의 기능이 변경되어도 클라이언트를 업데이트할 필요가 없다.

REST는 독립적 진화를 하기 위해서 사용하는 것이다.

 

한 예는 웹이다.

웹 페이지를 변경했다고 웹 브라우저를 업데이트할 필요가 없다.

웹 브라우저를 업데이트했다고 웹 페이지를 변경할 필요도 없다.

HTTP명세와 HTML 명세가 변경되어도 웹은 잘 동작한다.

 

그러나 모바일의 경우 문제를 겪는다.

서버의 기능이 바뀌면 앱의 업데이트를 해야 한다.

웹은 하위 버전과 호환되게 엄청난 노력을 기울였기에 이런 문제가 생기지 않은 것이다.

 


REST API

우리가 흔히 보는 REST API들 중 self-descriptive와 HATEOAS를 지킨 api는 거의 없고 이것들은 사실 REST API라고 부르면 안된다.

 

Self-descriptive

확장 가능한 커뮤니케이션.

서버나 클라이언트가 변경되더라도 오고가는 메시지는 언제나 self-descriptive 하므로 언제나 해석이 가능하다.

 

HATEOAS

애플리케이션 상태 전이의 late binding

어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.(링크가 동적으로 변경될 수 있다)

Ex) 서버가 링크를 바꾼다고 해도 그냥 바뀐 링크를 보고 따라가면 된다. 언제나 마음대로 바꿀 수 있다. 

어떤 상태로 전이가 완료되고 나서야 그 다음 상태가 결정된다는 것은 어떤 링크를 따라 페이지에 가면 그 페이지에 나온 하이퍼링크를 보고 나서야 그 다음 상태로 간다는 이야기이다.

 

  웹페이지 HTTP API
Protocol HTTP HTTP
커뮤니케이션 사람-기계 기계-기계
Media Type HTTP JSON
  HTML JSON
HyperLink 된다.(a 태그 등) 정의되어있지 않다.
Self-descriptive 된다.(HTML 명세) 불완전하다.

HTML

GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: text/html

<html>
<body>
<a href="https://todos/1">회사 가기</a>
<a href="https://todos/2">집에 가기</a>
</body>
</html>

Self-descriptive

  1. 응답 메시지의 Content-Type을 보고 mediat type이 text/html 임을 확인한다.
  2. HTTP 명세에 media type은 IANA에 등록되어있다고도 하므로 IANA에서 text/html의 설명을 찾는다.
  3. IANA에 따르면 text/html의 명세는 http://www.w3.org/TR/html 이므로 링크를 찾아가 명세를 해석한다.
  4. 명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이를 해석할 수 있다

HATEOAS

a 태그를 이용해 표현된 링크를 통해 다음 상태로 전이될 수 있으므로 HATEOAS를 만족한다.

 

 

JSON

GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/json
[
	{"id": 1, "title": "회사 가기"},
	{"id": 2, "title": "집에 가기"}
]

Self-descriptive

  1. 응답 메시지의 Content-Type을 보고 media type이 application/json 임을 확인한다.
  2. HTTP 명세에 media type은 IANA에 등록되어있다고 하므로, IANA에서 application/json의 설명ㅇ르 찾는다.
  3. IANA에 따르면 application/json의 명세는 draft-ietf-jsonbis-rfc7159bis-04 이므로 링크를 찾아가 명세를 해석한다.
  4. 명세에 json 문서를 파싱하는 방법이 명시되어있으므로 성공적으로 파싱에 성공한다. 그러나 "id"가 무엇을 의미하고, "title"이 무엇을 의미하는지 알 방법은 없다.

따라서 self-descriptive하지 않다.

 

HATEOAS

다음 상태로 전이할 링크가 없다.

 

따라서 HATEOAS하지 않다.

 


JSON의 Self-descriptive 해결 방법

1. Media Type

  1. 미디어 타입을 하나 정의한다.
  2. 미디어 타입 문서를 작성한다. 이 문서에 "id"와 "title"이 무엇인지 의미를 정의한다.
  3. IANA에 미디어 타입을 등록한다. 이때 만든 문서를 미디어 타입의 명세로 등록한다.
  4. 이제 이 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 이 메시지의 의미를 온전히 해석할 수 있다.

단점 : 매번 media type을 정의해야 한다.

 

2. Profile

  1. "id"와 "title"이 무엇인지 의미를 정의한 명세를 작성한다.
  2. Link 헤더에 profile relation으로 해당 명세를 링크한다.
  3. 이제 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 이 문서의 의미를 온전히 해석할 수 있다.

단점 :

  1. 클라이언트가 Link 헤더와 profile을 이해해야 한다.
  2. Content negotiation을 할 수 없다.

JSON의 HATEOAS 해결 방법

1. data

data에 다양한 방법으로 하이퍼링크를 표현한다.

 

단점 : 링크를 표현하는 방법을 직접 정의해야한다.

 

2. HTTP 헤더

Link, Location 등의 헤더로 링크 표현

'로드맵 > API' 카테고리의 다른 글

REST - Roy Fielding dissertation 번역 요약  (0) 2020.08.25
Comments