그런 REST API로 괜찮은가

skh951225·2023년 3월 8일
0

출처 : 그런 REST API로 괜찮은가 Youtube

REST

REST의 정의

인터넷에 REST의 정의를 찾아보면 이런 설명이 나온다.

Representational State Transfer (REST) is a way of providing interoperability between computer systems over the Internet (reference)

Representational State Transfer ??? Interoperability ??? 상당히 난해한 단어로 설명하여 잘 와닫지 않는다.

Interoperability is the ability of different systems, devices, applications or products to connect and communicate in a coordinated way, without effort from the end user.(reference)

사용자가 노력하지 않아도 서로 다른 물체들 간에 잘 통신할 수 있다는 것 ??? 사용자가 노력하지 않아도 인터넷상에서 컴퓨터 시스템의 통신이 잘 되는 방식!?

REST의 등장

어떻게 인터넷에서 정보를 공유할 것인가?

↓ ↓ ↓

WEB(1991)! 정보들을 하이퍼 텍스트로 연결하자.
표현방식:HTML, 식별자:URI, 전송방법:HTTP

↓ ↓ ↓

How do I imporved HTTP without breaking the Web?
기존에 구축된 Web과의 호환성 문제 발생...
어떻게 하면 Web을 망가뜨리지 않고 HTTP를 향상시킬 수 있을까?

↓ ↓ ↓

Roy T.Fielding 이 REST라는 개념을 도입
HTTP Object model(1994-1996)
REST(1998) "REpresentational State Transfer:An Architectural Style for Distributed Hypermedia Interaction"
REST(2000) "Architectural Styles and the Design of Network-based Software Architectures"

결국 REST라는 개념은 Web을 망가뜨리지 않고 HTTP를 향상시키기 위해 나온 것이다.



API

API의 정의

인터넷에 API의 정의를 찾아보면 이런 설명이 나온다.

An application programming interface (API) is a way for two or more computer programs to communicate with each other. It is a type of software interface, offering a service to other pieces of software.

간단히 말해서 소프트웨어 간의 상호작용 하는 방식이라고 할 수 있다.

어쩌다가 REST API를 ..

XML-RPC(1998) by Microsoft -> SOAP
원격으로 다른 시스템의 Method를 호출할 수 있는 프로토콜

↓ ↓ ↓

Salesforce API(2000.2)
인터넷에 최초로 공개된 API, SOAP을 이용해서 API를 만들었는데 너무 복잡해서 장사가 잘 안됨

↓ ↓ ↓

filer API(2004.8)
SOAP, REST를 이용해서 각각 만듦. REST가 SOAP에 비해서 훨씬 짧았음
결국 사람들은 SOAP(복잡,규칙 많음, 어렵다), REST(단순,규칙 적음, 쉽다) 라는 느낌을 받음
결국 SOAP 멸망.. REST 인기 급상승!!!

↓ ↓ ↓

결국 2006년 AWS가 자사 API의 사용량의 85%가 REST임을 밝힘
2010년 Salesforce.com 도 REST API 추가
REST의 승리!!ㄷㄷ

↓ ↓ ↓

CMIS(2008)
CMS를 위한 표준
EMC,IBM,Microsoft등이 함께 작업
REST 바인딩 지원

↓ ↓ ↓ Roy T.Fielding 曰 "No REST in CMIS" , "CMIS에는 REST가 없다"
↓ ↓ ↓

Microsoft REST API Guidelines(2016)

  • uri 는 https://{serviceRoot}/{collection}/{id} 형식이어야한다
  • GET, PUT, DELETE, POST, HEAD, PATCH, OPTIONS를 지원해야한다
  • API 버저닝은 Major.minor로 하고 uri에 버전 정보를 포함시킨다
  • 등등↓ ↓ ↓ Roy T.Fielding 曰
  • "s/REST API/HTTP API" 이건 REST API 아님; HTTP API 임;
  • "REST APIs must be hypertext-driven"
  • "REST API를 위한 최고의 버저닝 전략은 버저닝을 안 하는 것"



REST, 제약조건의 집합

Roy T.Fielding은 REST 논문에서 REST를 이렇게 정의했다.

An Architectural Style for Distributed Hypermedia Interaction

Hypermedia???

Hypermedia (eg. WEB)
Hypermedia, an extension of the term hypertext, is a nonlinear medium of information that includes graphics, audio, video, plain text and hyperlinks.(reference)

Hypermedia는 Media를 hyperlink로 비선형적으로 연결하는 매개체이다.

REST는 여러 제약조건의 집합이기때문에 Hybrid Architectural Style이라고도 불린다. REST의 제약조건은 다음과 같다.

  1. client-server
  2. stateless
  3. cache
  4. uniform interface
  5. layered system
  6. code-on-demand(optional)

HTTP 만 잘 따라도 대체로 1,2,3,5는 잘 지킨다.
code-on-demand 는 server 에서 코드를 client로 보내서 잘 실행될 수 있어야한다는 것이다.(Javascript 쓰면 됨)

그러나 uniform interface는 잘 만족하지 못한다.

Uniform Interface

  • identification of resources : resource가 uri로 잘 식별되면 된다. (대체로 잘 지켜짐)
  • manipulation of resources through representations(GET, POST...) (대체로 잘 지켜짐)
  • self-descriptive messages
  • hypermedia as the engine of application state(HATEOAS)

Self-descriptive

Self-descriptive. 즉, 메시지는 스스로를 설명해야한다.

  1. 목적지가 빠져있는 경우
GET / HTTP1.1

# Self-descriptive X
↓ ↓ ↓
GET / HTTP1.1
Host: www.example.org

# Self-descriptive O
  1. 어떤 문법을 썼는지 명시하지 않은 경우
HTTP/1.1 200 OK

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

# Self-descriptive X. body의 내용을 해석하는 방법을 모름
↓ ↓ ↓
HTTP/1.1 200 OK
Content-Type: application/json

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

# Self-descriptive X.
# body의 내용을 해석하는 방법(json)은 OK , but 의미를 모름 (op,path가 무엇을 의미하는지?)
↓ ↓ ↓
HTTP/1.1 200 OK
Content-Type: application/json-patch+json

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

# Self-descriptive O 
# IANA 의 json-patch+json 라는 media type의 명세를 찾아가면 의미도 해석 가능

HATEOAS


Hypermedia As The Engine Of Application State(HATEOAS). 즉, application의 상태는 hyperlink를 이용해 전이되어야한다.

HTML의 경우 HATEOAS를 잘 만족한다. a tag 를 통해서 하이퍼링크가 나와 있고, 이 하이퍼링크를 통해서 그 다음 상태로 전이가 가능하다.

JSON도 HATEOAS를 만족할 수 있다. LINK라는 헤더를 통해 이 메시지/Resource와 하이퍼링크로 연결되어 있는 다른 resource를 가르킬 수 있다.

REST 가장 큰 목적, 독립적 진화

REST의 시작은 'How do I imporved HTTP without breaking the Web?' 라는 질문에서 시작되었다. 서버가 변경되었는데 클라이언트가 변경될 필요가 없는 것, 바로 독립적 진화를 하기위해서 이다.

REST로 인한 WEB의 독립적 진화

WEB은 실제로 독립적 진화를 하고있다!

  • Web page를 변경했다 하더라도 브라우저를 업데이트할 필요는 없다.
  • 웹 브라우저를 업데이트 했다고 웹 페이지를 변경할 필요도 없다.
  • HTTP 명세가 변경되어도 웹은 잘 동작한다.(eg. HTTP2.0(2014))
  • HTML 명세가 변경되어도 웹은 잘 동작한다.

상호운용성(interoperability)에 대한 집착 : 이렇게까지??..

  • referer 오타지만 안 고침(원래는 referrer가 맞음)
  • charset 잘못 지은 이름이지만 안 고침(encoding이라고 지었어야함)
  • HTTP 상태코드 418 포기함(I'm a teapot, 만우절 장난으로 만든 HTCPCP가 418을 써서)
  • HTTP/0.9 아직도 지원함(크롬,파이어폭스)

REST가 웹의 독립적 진화에 도움을 주었는가?

  • HTTP에 지속적으로 영향을 줌
  • Host 헤더 추가 (REST Architecture 를 만들기 위해서 Host 헤더가 필요하다고 확신)
  • 길이 제한을 다루는 방법이 명시(414 URI Too Long 등)
  • URI에서 리소스의 정의가 추상적으로 변경됨:"식별하고자하는 무언가"(예전에는 문서의 위치)
  • 기타 HTTP와 URI에 많은 영향을 줌
  • HTTP/1.1 명세 최신판에서 REST에 대한 언급이 들어감
  • Roy T.Fielding이 HTTP 와 URI 명세의 저자 중 한명이라 REST의 영향을 많이 받음

REST API

REST API는 REST 아키텍쳐 스타일을 따라야한다. 오늘날 스스로 REST API라고 하는 API들의 대부분이 REST 아키텍쳐 스타일을 따르지 않는다. SOAP에 비해 쉬워 보여 REST를 사용했던 것인데, 사실 쉬운 것도 아니였다.

사람들은 Roy T.Fielding에게 물었다.
Q : "REST API도 저 제약조건들을 다 지켜야 하는건가?"
Roy T.Fielding : "ㅇㅇ 지켜야함"
Q : "원격 API가 꼭 REST API여야 하는건가?"
Roy T.Fielding : "시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지마라"

왜 API는 REST가 잘 안되는가?

  • 적어도 문법은 정의되어 있음, 하지만 의미는 정의되어 있지 않음
    JSON이 문제인가 보네..

HTML vs JSON

  • HTML

(1) Self-descriptive
1. 응답 메시지의 Content-Type을 보고 media type이 text/html임을 확인한다.
2. HTTP 명세에 media type은 IANA에 등록되어있다고 하므로, IANA에서 text/html의 설명을 찾는다.
3. IANA에 따르면 text/html의 명세는 http://www.w3.org/TR/html 이므로 링크를 찾아가 명세를 해석한다.
4. 명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이를 해석하여 문서 저자가 사용자에게 이 메시지의 힌트만으로 온전한 해석을 할 수 있게 해준다.

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

  • JSON

    (1) 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 X)

(2) HATEOAS
다음 상태로 전이할 링크가 없다. (HATEOAS X)

그런데 Self-descriptive와 HATEOAS가 독립적 진화에 어떻게 도움이 될까?

  • Self-descriptive : 확장 가능한 커뮤니케이션을 가능하게 한다. 메시지는 언제나 self-descriptive 하므로 언제나 해석 가능하다.
  • HATEOAS : 어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.즉, 링크는 동적으로 변경될 수 있다.(독립적)

REST API가 되기 위해서...

self-descriptive 해결

  1. Media type

    미디어 타입을 하나 정의한다. 미디어 타입 문서를 작성한다. 이 문서에 id,title의 의미를 정의한다. IANA에 미디어 타읍을 등록한다. 이 때 만든 문서를 미디어 타입의 명세로 등록한다. 이제 이 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 이 메시지의 의미를 온전히 해석할 수 있다.(단점 : 매번 media type을 정의해야한다)
  2. Profile

    id, title의 의미를 정의한 명세를 작성한다. Link 헤더에 prrofile relation으로 해당 명세를 링크한다.이제 이 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 이 메시지의 의미를 온전히 해석할 수 있다.(단점 : 클라이언트가 Link헤더(RFC 5988)와 profile(RFC 6906)을 이해해야하고 Content negotiation을 알 수 없다.)

    Content negotiatoin : content negotiation 은 user agent가 사용자에게 가장 알맞는 형태의 리소스를 받을 수 있도록, 리소스를 어떤 형태로 받을지 정할 수 있도록하게 하는 메커니즘입니다.

HATEOAS 해결

  1. data로

(1) data에 다양한 방법으로 하이퍼링크를 표현한다.(단점 : 링크를 표현하는 방법을 직접 정의해야한다)

(2) JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용한다.(단점 : 기존 API를 많이 고쳐야함)

  1. HTTP 헤더로

    Link, Location등의 헤더로 링크를 표현한다.

Hyperlink는 반드시 uri?

다 괜찮음

Media type 등록은 필수인가? NO! 의도한 청중이 이해할 수만 있다면 상관없다. 왠만하면 Media type을 IANA에 등록해라. 누구나 쉽게 사용할 수 있게되고, 이름 충돌을 피할 수 있다. 등록이 별로 어렵지 않다(고주장함).

요약

오늘날 대부분의 "REST API"는 사실 REST를 따르지 않고 있다.
REST의 제약조건 중에서 특히 Self-descriptive 와 HATEOAS를 잘 만족하지 못한다.
REST는 긴 시간에 겇려(수십년) 진화하는 웹 어플리케이션을 위한 것이다.
REST를 따를 것인지는 API를 설계하는 이들이 스스로 판단하여 결정해야한다.
REST를 따르겠다면, Self-descriptive 와 HATEOAS를 만족시켜야한다.

  • Self-descriptive는 custom media type이나 profile link relation 등으로 만족시킬 수 있다.
  • HATEOAS는 HTTP 헤더나 본문에 링크를 담아 만족시킬 수 있다.

REST를 따르지 않겠다면,"REST를 만족하지 않는 REST API"를 뭐라고 부를지 결정해야 할 것이다.

  • HTTP API라고 부를 수도 있고
  • 그냥 이대로 REST API라고 부를수도 있겠다.(Roy가 싫어함)

0개의 댓글