개발/Concept

[Web] 그런 REST API로 괜찮은가?

ch4njun 2021. 3. 25. 12:16
반응형

www.youtube.com/watch?v=RP_f5dMoHFc&t=1004s

본 내용은 위 유튜브 영상을 참고해 제작되었음을 알립니다.

 

 

REST 란?


REpresentational State Transfer 의 약자이다. 이렇게 보면 무슨 의미인지 정확히 모르기 때문에 한 가지 내용을 살펴보자.

 

Roy T. Fielding이 HTTP를 정립하고 명세에 기능을 더하고 기존의 기능을 고쳐야하는 상황에 놓였는데, 이렇게 고치게되면 기존에 구축되어있는 웹 서버와의 호환성에 영향을 미칠 수밖에 없다.

그래서 "어떻게하면 기존 웹을 망가뜨리지 않고 진보할 수 있을까?" 라는 질문에 나온 답이 HTTP Object Model 이고, 1998년에 REST로 최초로 공개가 된다.

기존에 나온 SOAP를 기반으로 나온 API는 너무 복잡했고 이어서 나온 REST를 기반으로 하는 REST API는 간단했다. 그래서 사용자들이 느끼기에 REST는 "단순하고, 규칙이 적고, 쉽다" 였다.

 

2006년에 AWS 자사 API의 사용량의 85%가 REST 임을 밝힘으로써 REST가 승리하게 된다.

 

No REST API?


2008년에 CMIS라는 CMS를 위한 표준이 나왔다. EMC IBM, Microsoft등이 참여했고 여기서 REST 바인딩을 지원한다. 그러나, REST를 만든 Roy T. Fielding은 "CMIS에는 REST가 없다" 라고한다.

 

2016년에 Microsoft에서 REST API Guidelines를 발표한다. 사람들이 보기에는 합리적이고 좋은 REST API에 부합하는 것 같았지만, Roy T. Fielding은 "s/REST API/HTTP API" 라고하면서 REST API가 아님을 밝혔다.

 

그러면서 Roy T. Fielding은 "REST API는 반드시 Hypertext-driven 이여야 한다." 라고 발표한다.

 

What's REST API?


REST 아키텍처 스타일을 따르는 API.

REST는 분산 하이퍼미디어 시스템을 위한 아키텍쳐 스타일.

아키텍쳐 스타일은 제약조건의 집합.

그렇기 때문에 이러한 제약조건들을 모두 지켜야 REST API라고 부를 수 있다.

 

  • Client-Server
  • Stateless
  • Cache
  • Uniform Interface
  • Layered System
  • Code-on-demand (optional)

REST는 위 6가지 아키텍쳐 스타일로 이루어져 있다. 그러나 오늘날 HTTP만 잘 따라도 Uniform Interface를 제외한 아키텍쳐 스타일은 대체적으로 잘 지킬 수 있다.

 

그렇기 때문에 Uniform Interface 아키텍쳐 스타일만 살펴보자.

  • Identification of resource (리소스가 URI로 식별되면 된다.)
  • Manipulation of resources through representations (Representation 전송을 통해 리소스를 조작해야 한다.)
  • Self-descriptive Message
  • Hypermedia as theengin of application state (HATEOAS)

Uniform Interface의 제약조건은 위 4가지이고, 그 중에서도 지켜지지 않는 제약조건은 3, 4번째 제약조건이다. 하나씩 살펴보자.

 

Self-descriptive message

특정 메시지를 봤을 때, 해당 메시지의 내용만을 가지고 사용자가 충분히 이해가 가능해야 한다는 제약조건이다.

 

예를 들어, 다음은 Self-descriptive message가 아니다. 왜냐하면, 이렇게 Response된 메시지가 무슨 메시지인지 알 수 없기 때문이다.

 

따라서 다음 사진과 같이 해당 메시지가 JSON 형태의 메시지임을 알려야 한다. 그렇다면 이 메시지는 Self-descriptive message일까? 

 

아니다. 왜냐하면, "op", "path" key값이 각각 무엇을 의미하는지 해석할 수 없기 때문이다. 따라서 다음 사진과 같이 해당 JSON에 대한 명세를 추가해 "op" key값의 의미는 무엇이고, "path" key값의 의미는 무엇인지 알 수 있도록 해줘야 이 메시지는 Self-dscriptive message라고 할 수 있다.

 

그러면 이러한 Self-descriptive 는 어떻게 도움이 될까? 바로 "확장 가능한 커뮤니케이션"이 가능하도록 한다. 서버나 클라이언트가 변화하더라도 메시지는 언제나 Self-descriptive하기 때문에 언제나 해석이 가능하다는 말이다.

HATEOAS

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

 

 

HTML 같은 경우를 보면 <a> 태그를 통해서 Hyperlink가 나와있고 이를 통해 상태가 전이가 될 수 있기 때문에 HTML은 HATEOAS를 만족한다고 할 수 있다.

 

JSON에서도 HATEOAS를 만족할 수 있는 방법은 있는데, 위와 같이 Link 헤더를 사용하는 것이다.

 

HATEOAS는 어떻게 도움이 될까? 바로 "애플리케이션 상태 전이의 Late Binding"이 가능하다는 점이다. 애플리케이션이 어디로 전이될지 미리 결정해 놓는 것이 아니라, 어떤 상태로 전이가 완료되고 나서야 다음 전이될 수 있는 상태를 결정한다는 말이다. 즉, 링크는 동적으로 변경될 수 있다는 뜻이다.

 

Why Uniform Interface?


그렇다면 이러한 Uniform Interface 제약조건은 왜 지켜야할까?

 

독립적인 진화를 하기 위함이다. 이는 서버의 기능이 변경되어도 클라이언트를 업데이트할 필요가 없다는 것이다. 이 것이 바로 Roy T. Fielding이 REST를 만든 이유이다.

 

REST가 지켜지고 있는 가장 대표적인 예로는 "웹"이 있다. 웹이 변경되었다고 웹 브라우저를 업데이트 할 필요는 없다. 반대로 웹 브라우저를 업데이트했다고 하더라도 웹에는 정상적으로 접속이 된다. 심지어 HTTP 혹은 HTML 명세가 바껴도 정상적으로 동작한다.

 

이러한 것이 독립적인 진화를 지키고 있는 REST의 예시이다.

 

REST API?


REST API란 REST 아키텍쳐 스타일을 따르는 API를 말한다. 그러나 오늘날 스스로 REST API라 부르는 대부분은 REST 아키텍쳐 스타일을 따르지 않는다.

 

Roy T. Fielding이 말하길 REST API란, Hypertext를 포함한 Self-descriptivie한 메시지의 Uniform Interface를 통해 리소스에 접근하는 API이다. 이 말은 REST API는 위에서 언급한 REST의 모든 제약조건을 지켜야 한다는 의미이다.

 

그렇다면, 우리가 만드는 API를 이렇게 복잡하고 어려운 REST API로 만들어야 할까?

Roy T. Fielding은, 시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면 REST에 대해 따지느라 시간을 낭비하지 않아도 상관없다고 말했다. 

 

How REST API?


우리가 만드는 API가 왜 REST가 잘 안되는지 확인하기 위해 REST가 잘 구현되어 있는 웹과 비교해보자.

 

HTTP API에서 사용하는 Media Type은 JSON이고, JSON에는 Hyperlink가 정의되어있지 않고, Self-descriptive도 불완전하기 때문에 우리가 개발하는 API에서는 REST를 구현하기 어려운 것이다.

 

그러면 JSON 메시지가 Self-descriptive, HATEOAS 제약조건을 지키도록 하는 방법을 살펴보자.

 

Self-descriptive

방법1: Media type

 

Media Type을 하나 정의하고, 문서를 작성해 IANA에 해당 문서를 해당 Media Type 명세를 등록한다. 이제 해당 메시지를 보는사람이 "id", "title" key값이 뭔지를 해당 명세를 통해서 확인할 수 있기 때문에 Self-descriptive 제약조건을 성공적으로 지킨 메시지가 된다.

 

하지만 단점은 매번 Media Type을 정의하는 것은 매우 번거롭다.

 

방법2: Profile

 

해당 메시지에 대한 명세를 작성하고 Link 헤더에 profile relation으로 해당 명세를 링크한다. 이제 메시지를 보는 사람이 해당 링크를 통해 명세를 확인할 수 있기 때문에 Self-descriptive 제약조건을 성공적으로 지킨 메시지가 된다.

 

하지만 클라이언트가 Link헤더와 profile을 이해해야 하고, Content Negotiation을 할 수 없다는 단점이 있다.

 

HATEOAS

방법1: data

 

이와 같이 단순히 data에 링크를 박아 넣어서 HATEOAS 제약조건을 만족할 수 있다.

 

방법2: Location, Link 헤더

 

정리


  • 오늘날 대부분의 REST API들은 사실 Roy T. Fielding이 말하는 REST를 따르지 않고 있다.
  • REST의 제약조건 중에서 Uniform Interface의 Self-descriptive와 HATEOAS를 잘 만족하지 못한다.
  • REST는 긴 시간에 걸쳐 진화하는 웹 애플리케이션을 위한 것이다.
  • REST를 따를 것인지 API를 설계하는 이들이 스스로 판단하여 결정해야 한다.
  • REST를 따르겠다면, Self-descriptive와 HATEOAS를 만족시켜야 한다.
    Self-descriptive는 custom media type이나 profile link relation 등으로 만족시킬 수 있다.
    HATEOAS는 HTTP 헤더나 본문에 링크를 담아 만족시킬 수 있다.

 

반응형