REST API

흑이·2022년 3월 18일
0
post-custom-banner

스터디 주제로 REST API에 대해 조사하며 공부하였다.

DEVIEW 발표 그런 REST API로 괜찮은가 영상을 보며 많은 도움이 되었고 개인적으로 재밌었기 때문에 해당 영상으로 무식하게 발표자가 말하는 것을 빼먹지 않고 정리 하였다.

REST의 탄생 배경, REST를 통해 웹의 독립적 진화 가능, REST API의 구현 등...

덕분에 REST API가 무엇인지 어느정도 알 수 있었던것 같다.

또한 오늘날 대부분의 "REST API"는 사실 REST를 따르지 않고 있고 현실적으로 불가능한 경우도 있기 때문에 REST하지 않지만 REST API라고 부르는 것이 아닐까 라고 생각한다...







REST 란?

  • REpresentational State Transfer
  • a way of providing interoperability between computer systems on the internet(컴퓨터 시스템간의 상호운영성을 제공하는 방법 중 하나다)


REST의 탄생 역사

시작은 WEB(1991)

Q: 어떻게 인터넷에서 정보를 공유할 것인가?
A: 정보들을 하이퍼텍스트로 연결한다.
(질문의 해답으로 WEB이 나옴)

  • 표현 형식: HTML
  • 식별자 : URI
  • 전송 방법: HTTP


  • HTTP라는 프로토콜을 설계하는 여러명 중 대학원생이였던 Roy T.Fielding 이라는 사람이 작업을 하면서 고민을 하게 됨
  • 94년에 HTTP/1.0 명세가 나오기 전에 HTTP는 WWW의 프로토콜로 사용중이였으며, WEB은 급속도로 성장중이였음, 이미 전 세계 수많은 WEB서버가 존재 함
  • Roy는 HTTP를 정립하고 명세에 기능을 더하고 기존 기능을 고쳐야 하는 상황
  • HTTP를 고치게 되면 기존에 이미 구축되어 있는 웹 하고 호환성의 문제가 생기는 것을 피하기 어렵다.
  • 어떻게 하면 WEB을 망가뜨리지 않고 HTTP를 진보 시킬 수 있을까? 고민을 해서 답을 내놓음
  • HTTP Object Model 이것이 후에 REST(1998)라는 이름으로 발표를 한다. 그리고 이걸 2000년에 박사 논문으로 발표한다.


API 등장

  • 98년에 마이크로소프트가 원격으로 다른 시스템에 메소드를 호출할 수 있는 XML-RPC 프로토콜을 만든다.
  • 이것이 나중에 SOAP이라는 이름으로 바뀜
  • SOAP이란? 일반적으로 널리 알려진 HTTP, HTTPS, SMTP 등을 통해 XML 기반의 메시지를 컴퓨터 네트워크 상에서 교환하는 프로토콜


  • Salesforce 라는 회사에서 최초의 API를 공개(2000.02)
  • SOAP을 이용해 API를 만듬
  • 굉장히 복잡해서 인기가 없었다.


4년 후에 flickr에서 API 등장
SOAP



REST

  • SOAP에 비해 REST가 짧았다.


  • REST API가 SOAP API 보다 인기가 더 많아 진다.
  • 2006년 AWS가 자사 API의 사용량의 85%가 REST임을 밝힘


  • 2008년에 CMS를 위한 표준


  • Roy Fielding은 CMIS는 REST가 아니라고 한다.


  • 2016년도에 Microsoft가 REST API Guidelines을 만듬
  • Roy Fielding은 이것도 REST API가 아니고 HTTP API라 해야한다고 함


사람들이 알고 있던 REST API와 REST를 만들었던 Roy Fielding이 말하는 REST가 다르다

  • 뭐가 문제여서 그럴까~?


REST API란?

  • REST 아키텍쳐 스타일을 따르는 API


REST는?

  • 논문에는 분산 하이퍼미디어 시스템(예: 웹)을 위한 아키텍쳐 스타일이라고 한다.


아키텍쳐 스타일이란 무엇일까?

  • 제약 조건의 집합


그래서 이 제약 조건들을 모두 지켜야 REST를 따른다 라고 말한게 가능하다.

  • 사실 REST는 아키텍쳐 스타일 이면서 동시에 하이브리드 아키텍쳐 스타일이라고 말한다,
  • 왜냐하면 아키텍쳐 스타일인데 동시에 아키텍쳐 스타일의 집합이다.

code-on-demand(optional) 이란?

  • 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 된다. (자바스크립트)

거의 모든 스타일을 지키는데 이중에 단 하나 Uniform Interface을 잘 만족하지 못한다.



상위 두 개는 잘 지켜지고 있다.

  • Indetification of resources : 리소스가 URI로 식별된다.
  • manipulation of resources through representations : 리프리젠테이션 전송을 통해서 리소스를 조작해야 한다. 리소스를 만들거나, 수정하거나, 삭제할 때 Http 메시지에 표현을 담아서 전송해야 한다.

이 두가지는 REST API 라고 알려진 거의 모든 것들이 지키지 못하는 것들이다.

  • Self-descriptive message : 메시지는 스스로를 설명해야 한다
  • hypermedia as the engine of application state(HATEOAS): 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.


Self-descriptive message

  • 요청 메세지에 목적지가 빠져있다. 이런경우 Self-descriptive 하지 않다.



응답 메세지

  • 이것 역시 self descriptive 하지 못하다. 왜냐하면 이 메세지를 해석해야하는데 어떠한 문법으로 작성되었는지 모름


self descriptive가 되려면 Content-Type 헤더가 반드시 필요하다.

  • Content-Type 헤더에 application/json이라고 되어 있으면 대괄호, 중괄호 큰 따옴표의 감싸있는 문자열의 의미를 이해할 수 있어, 파싱이 가능해지고 문법을 해석할 수 있게 된다.

  • 이렇게 추가하여도 self descriptive인가? 아니다.

  • 왜냐하면 op와 path가 무엇을 의미하는지 알 수 없다.

  • 이것만으로 부족하기 때문에 application/json-patch+json 되어 있으면

  • patch+json이라는 미디어 타입으로 정의되어 있는 메시지 이기 때문에, patch+json의 명세를 찾아가서 이해하게 되면 그제서야 올바르게 이 메세지를 이해할 수 있다.

  • 즉 메시지 내용으로 온전히 해석이 가능해야하는데, 하지만 오늘날의 REST API는 대부분 그렇지 않다.



HATEOAS

  • 하이퍼 링크를 통한 애플리케이션 상태를 전이 한다.


  • html을 보면, a 태그를 통해 하이퍼 링크가 있고 상태 전이를 하기 때문에 HATEOAS다.


  • json으로 표현해도 만족하는 방법이 있다.
  • Link라는 헤더를 이용한다. 하이퍼 링크로 이 리소스와 연결되어 있는 다른 리소스를 가리킬 수 있는 그런 기능을 제공해 준다.
  • 이전 게시물에 uri가 /articles/1 이고 그 다음 uri는 /articles/3 이다. 라는 정보를 표현
  • 또한 이 정보는 Link헤더가 이미 표준으로 문서가 나와있기 때문에 이 메시지를 보는 사람이 해석을 해서 어떻게 링크가 되어 있는지 이해하고 하이퍼 링크를 타고 다른 상태로 전이가 가능하다.
  • 따라서 HATEOAS를 만족 한다.


왜 Uniform Interface를 해야하나?

독립적 진화를 하기 위해서

  • 서버와 클라이언트가 각각 독립적으로 진화한다.
  • 서버의 기능이 변경되어도 클라이언트를 업데이트할 필요가 없다.(새로운 API가 추가,변경,삭제되어도)
  • REST를 만들게 된 계기 : "How do I improve HTTP without breaking the Web."


그럼 REST가 지켜지는 사례는?

  • 웹 사이트에서 웹 페이지가 변경됐다고 해서 그 웹 페이지에 접근 할때 웹브라우저로 새로 업데이트 할 필요가 없다.

  • 기존에 사용하고 있던 웹 브라우저로 접속이 잘 된다.

  • URI, 그림, 내용이 바뀌어도 내가 사용하는 웹 브라우저로 항상 접속이 잘 된다.

  • 반대로 예를들어 크롬 32에서 33으로 업데이트 하고 사이트에 들어가도 접속이 잘 된다.

  • 심지어 HTTP 명세가 바뀌어도 접근이 잘 된다. (HTTP 2.0 ~ 버전 업을 해도 접속이 잘 된다.)

  • 모바일은 REST 아키텍쳐 스타일을 따르고 있지 않아서, 클라이언트도 서버에 맞게 업데이트를 해줘야 한다.



웹은 어떻게 독립적 진화를 할 수 있었을까?

  • W3C Working groups
  • IETF Working groups
  • 웹 브라우저 개발자들
  • 웹 서버 개발자들
  • 이런 수많은 개발자들의 노력을 통해서 가능해짐
  • HTML5 첫 초안에서 권고안 나오는데까지 6년
  • HTTP 개정판의 경우 7년동안 토론을 했는데 기능이 하나도 추가되지 않고 문서만 다듬었다. 왜냐하면 하위호환성을 깨지 않기 위해서이다.


  • Referer에 r이 빠져있음. 처음에 만들 떄 오타
  • 못 고친다.. 왜냐하면 이것을 고치는 순간 웹이 꺠짐
  • charset도 잘못 지은 이름, 원래대로라면 incoding 이라고 이름을 지어야 함
    그떄 이름 짓던 사람들이 인코딩에 대한 개념이 없어 잘못 지음
  • 고치지 않고 그대로 사용.. 왜냐하면 이름을 고치면 상호 운용성이 깨지기 때문에


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

  • 옛날에 URI는 문서 위치라고 정의가 되어있었음


그럼 REST는 성공했는가?



그런데 REST API는?



REST API도 저 제약조건들을 다 지켜야 하는건가?

  • 하이퍼텍스트를 포함한 self-descriptive한 메시지의 uniform interface를 통해 리소스에 접근하는 API
  • Roy T.Fielding는 명시적으로 REST API는 제약 조건을 지켜야 한다고 말함.
  • self-descriptive와 hateos 를 지켜야 한다고..


우리가 만든 원격 API가 꼭 REST API여야 하는가?

시스템 전체를 통제할 수 있거나 진화에 관심이 없다면 하지마라. 백엔드 개발자가 프론트 개발자를 완벽히 통제 가능하거나, 혼자서 개발하거나 이런 경우.

  • 시스템 전체를 통제할 수 있다는 것은 내가 서버 개발자라면 클라이언트 개발자를 통제 가능한 상황
  • 클라이언트와 서버를 다 만드는


그럼 이제 어떻게 할까?



일단 왜 API는 REST가 잘 안되나?

  • 일반적인 웹과 비교를 해보자

  • 웹 페이지들은 사람이 봄, 그런데 API는 기계가 해석함
  • 예를 들면 모바일 앱이 해석하거나 메시지를 기계가 해석함 그러다 보니 미디어 타입이 다름
  • 웹 페이지는 HTML이고 HTTP API인 경우에는 JSON이나 XML같이 기계가 이해할 수 있는 기계가 의미를 이해할 수 있는 포맷을 쓰게 됨


  • html 명세를 보면 html을 사용할 수 있는 모든 태그들이 다 정리되어 있다.
  • JSON은 그런게 없음..
  • JSON의 오브젝트 안에 들어갈 수 있는 key, value가 어떤 의미를 가져야 하는지 정해진것이 없다..
  • 그래서 불완전 하다는 것은 문법은 정의가 되어 있다.
  • 어떻게 파싱을 해라 중괄호 ~~ , 하지만 그 안에 들어가 있는 값들이 어떤 의미를 가져야 된다는 정리가 안되어 있다.

    문법 해석은 가능하지만, 의미를 해석하려면 별도로 문서가(API 문서 등) 필요하다.



HTML은 Self-descriptive 한가?

  • 이 메시지에에 들어있는 힌트만으로 이 메시지를 온전히 해석이 가능하다.
  • 따라서 Self-descriptive 하다.


HTML은 HATEOAS를 만족한가?

  • a 태그를 이용해 다음 상태로 전이 가능함
  • 따라서 HATEOAS를 만족한다.


JSON은 Self-descriptive 한가?

  • 파싱은 성공하지만 Key와 Value가 무엇을 의미하는지 알 수가 없다.
  • 따라서 Self-descriptive 하지 않다.


JSON은 HATEOAS를 만족한가?

  • 다음 상태로 전이할 링크가 없다..
    - 따라서 HATEOAS를 만족하지 않는다.


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

Self-descriptive

- 확장 가능한 커뮤니케이션을 가능하게 한다.

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


HATEOAS

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

  • 어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.
  • 링크는 동적으로 변경될 수 있다.
  • 서버가 링크를 바꾼다고 해도 클라이언트의 동작은 전혀 문제가 없다.
  • 바뀐 링크를 그대로 따라가면 됨
  • 서버가 링크를 마음대로 동적으로 바꿀 수 있다. 따라서 독립적인 진화가 가능한 것


그럼 REST API로 고쳐보자

Self-descriptive

방법 1

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



방법 2

  • Content negotiation : user agent가 어떤 URI에 있는 리소스를 요청할 때, 해당 리소스가 사용자에게 적절한 형태로 받도록 정하게 해주는 방법

  • Content negotiation를 할 수 없는 이유 ?

  • 미디어 타입으로 판단하는게 아니라 Link 헤더만으로 판단하기 때문에



HATEOAS

방법 1

링크 헤더를 이용해서 프로필 문서에 정의를 하던지 아니면 미디어 타입을 정의 하던지 어떻게든 정의를 해야 함

  • 하이퍼 링크로 표현한 방법이 정해져 있는 문서가 있다.
  • JSON API, HAL, UBER....
  • 아까와는 달리 새로 방법을 정할 필요 없이 대신 기존 API를 수정해야 한다.(이 명세들이 요구하는 것에 맞게 고쳐야 된다.)


방법 2

- 결국에는 HATEOAS는 data, 헤더 모두 활용하면 좋다.



궁금점

그렇지 않다. 상태 URI도 상관 없다. 어쨌든 Hyperlink라는건 표현 되기만 하면 아무 상관 없다.



그렇지 않다. 의도한 저자가 이해할 수만 있으면 상관 없다.
회사 안에서만 쓰는 API고 그 사람들은 이 미디어 타입을 모두 이해하고 있다고 하면 IANA에 등록할 필요 없다.



하지만 등록하면 좋다. 왜냐하면





https://www.youtube.com/watch?v=RP_f5dMoHFc
https://restfulapi.net/resource-naming/
https://library.gabia.com/contents/8339/
https://meetup.toast.com/posts/92
https://yangbongsoo.gitbook.io/study/undefined-1/rest#1.-rest
https://blog.npcode.com/2017/03/02/%EB%B0%94%EC%81%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%93%A4%EC%9D%84-%EC%9C%84%ED%95%9C-rest-%EB%85%BC%EB%AC%B8-%EC%9A%94%EC%95%BD/
https://spoqa.github.io/2012/02/27/rest-introduction.html
http://haah.kr/2017/05/22/rest-the-beginning/

post-custom-banner

0개의 댓글