[HTTP] REST API란 무엇인가?

Yanison·2023년 2월 17일

네트워크

목록 보기
1/1

일반적으로 개발자들이 이해하는 REST API

API가 무엇일까?

API는 Application Programming Interface의 약자로 소프트웨어가 다른 소프트웨어로 정해진 형식으로 원격의 메소드를 호출하는 인터페이스를 의미한다. 꼭 네트워크 상에서만 API가 존재하는것은 아니다.
로컬 프로그램인 브라우저, 윈도우에서는 시스템이나 하드웨어로부터 정해진 지시대로 소프트웨어를 짤 수 있는 Windows API를 제공한다. '이 함수를 넣으면 윈도우가 이렇게 해준다'라는 간략한 지식만 알 수 있으면 시스템, 하드웨어의 깊은 지식 없이 개발자는 소프트웨어의 프로그래밍만 집중할 수 있게 된다는 의미이다.

그럼 (일반적으로 이해되는)REST API는 무엇일까?

REST라는 형식의 아키텍쳐를 따르는 API이다. 과거의 SOAP이란 요청방식을 대체하고 오늘날의 REST가 된 것 REST API의 특징으로는 각 요청이 어떤 동작 정보를 위한 것인지 그 요청의 모습 자체로도 이해를 할 수 있어야 한다.

그냥 시스템이 돌아가기만 하면 되면 되는게 아닐까? 왜 필요할까?

틀린말은 아니지만 서비스 규모가 커지고 공동으로 개발하는 사람들이 많아질수록 이런 REST를 따르지 않는다면 해당 서비스를 인수인계 받는다던가 혹은 서비스에서 제공하는 API를 사용해서 다른 제품을 만들 개발자들이 사용하는 경우 유지보수 측면에 있어서 복잡성이 증가하게 될것이다. 반대로 RESTful 하게 만든 API는 요청을 보내는 주소만으로도 그 요청의 의도를 온전히 파악할 수 있다. 아래의 예시 처럼 말이다.

서버와 클라이언트 사이 요청과 응답은 HTTP로 이루어지는데 이 HTTP 요청을 보낼때는 여러가지 메소드가 존제한다.

  • GET
    특정 자원을 보여주길 요청할때 사용하는 메소드
  • HEAD
    응답 body없이 GET의 identical 응답을 요청할때 사용하는 메소드
  • POST
    entity를 특정 자원에 submit 할때 사용하는 메소드 이다. 종종 서버에 상태 변경과 같은 side effect를 요청할때 사용한다.
  • PUT
    특정 target의 자원을 요청 payload에 담긴 자원으로 대체를 요청할때 사용하는 메소드이다.
  • DELETE
    특정 자원을 삭제를 요청할때 사용하는 메소드이다.
  • CONNECT
    요청한 자원에 대해 양방향 연결을 시작해주는 메소드이다.
  • OPTIONS
    목표 자원과의 통신 옵션을 설명하기 위해 사용된다.
  • TRACE
    유의미한 디버깅 메커니즘을 제공하는 특정한 자원의 경로를 따라 메세지 loop-back을 수행하기 위한 메소드이다.
  • PATCH
    자원의 부분적인 수정을 할 때에 사용된다.

mdn web docs _ https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PATCH

REST API에서는 주로 GET,POST,DELETE,PUT,PATCH를 사용한다.

POST,PUT,PATCH에는 BODY라는 주머니가 있어서 GET이나 DELETE보다 많은 정보들을 그리고 안전하게 감추어 담아서 서버로 보낼 수 있다.

하지만 각 요청메소드가 특정 기능에 제한되어져 있지 않다. 예를들어 POST 메소드만 해도 읽고,쓰고,삭제하고,수정하기가 모두 가능하다. 그렇지만 RESTful 한 API를 만들기 위해서는 각 메소드가 만들어진 의도에 따라 적절하게 사용해야한다.

예를들어

  • GET 메소드는 데이터를 조회 요청할때,
  • POST 새로운 데이터를 Create할 때 사용
  • PATCH는 데이터를 부분적으로만 수정할때 사용
  • PUT은 데이터를 완전히 수정할때 사용

위의 예시처럼 각 메소드의 정의된 역할에 맞게 사용함을 준수하는 것 처럼 말이다.

그리고 동시에 URI와 메소드를 함께 유추하여 요청의 의도를 온전히 해석할 수 있어야 RESTful 한 API라 할 수 있다. 아래의 예시를 보자

그리고 또다른 REST의 규칙 중 하나로 URI의 PATH를 명사로만 구성해야 한다는것, 해당 URI의 목적은 HTTP 메소드로 유추하도록 구성하는 것이다.

중간정리

RESTful 한 API는 URI가 명사로만 구성되어야 하고 HTTP 메소드와 URI만으로 요청의 의도를 온전히 해석할 수 있어야 한다는것

참고내용

얄팍한 코딩의 REST API가 뭔가요?
https://www.youtube.com/watch?v=iOueE9AXDQQ

여기까지가 일반적인 REST API에 대한 이해이다. 그렇다면 진정한 의미에서의 REST API는 무엇일까?

REST API의 탄생 배경

1991년 WEB의 창시자 팀 버너스 리가 어떻게 인터넷에서 정보를 공유할 것인가 라는 문제에 다음과 같이 답을 내렸다.

"모든 정보들을 하이퍼텍스트로 제공하면 될 것이고 아래와 같은 형식으로 제공한다."

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

HTTP/1.0 (1994-1996)
Roy T.Fielding "어떻게 웹을 망가뜨리지 않으면서 HTTP를 진보시킬수 있을까?"

해결책 : HTTP Object Model

4년 뒤(1998) REST라는 이름으로 소개가 되고
2년 뒤(2000) Roy T.Fielding, 약 120페이지의 박사 논문으로 발표가 되었다.

그럼 API는 무엇일까?

1998년 마이크로소프트에서 XML_RPX라는 원격으로 다른 시스템의 메소드를 호출 할 수 있는 프로토콜을 만들었다. -> SOAP

2000.02 Salesforce 에서 SOAP이란 이름으로 API를 공개하였다. 인터넷 세계에서 최초로 공개된 API였다.

메소드 하나를 가져오는 요청 분량, 굉장히 복잡했다. 그래서 인기가 없었다고..

4년 뒤(2004.08) flickr가 새로운 REST라는 이름으로 새로운 API를 발표했다.

REST와 SOAP의 비교 샷 REST가 훨씬 더 간결해보인다.

이런 비교로 결국 SOAP API는 아래의 그래프 처럼 REST API에 추월당하였다.

그리고 결국..

- 2006년 AWS가 자사 API의 사용량의 85%가 REST임을 밝힘
- 2010년, Salesforce.com, REST API 추가

그렇게 WWW세상에 REST 가 정착이 되나 싶었지만 2008년 CMIS가 발표가 되었다.

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

그리고 Roy T.Fielding은 이에 대해 다음과 같이 말했다.
"No REST in CMIS"

2016년에 Microsoft는 REST API에 대한 가이드 라인을 다음처럼 발표했다.

  • uri는 https://{sercerRoot}/{collection}/{id} 형식이어야 한다.
  • GET,PUT,DELETE,POST,HEAD,PATCH,OPTION을 지원해야 한다.
  • API 버저닝은 Major.minor로 하고 uri에 버전 정보를 포함시킨다.
  • 등등...

그리고 Roy T.Fielding은 이에 대해 다음과 같이 말했다.

  • "s/REST API/HTTP API/ (이것도 REST API 아님,이거는 그냥 HTTP API임)"
  • "REST APIs는 반드시 hypertext-driven 이어야 한다."
  • "REST API를 위한 최고의 버저닝 전략은 버저닝을 안 하는 것"

사람들이 생각했던 REST API하고 Roy T.Fielding가 발표했던 REST API는 너무나도 달랐다.
도대체 뭐가 문제였던 것일까?

REST API에 대한 정의

REST 아키텍쳐 스타일을 따르는 API를 REST API라고 한다.

그럼 REST는 무엇인가?

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

REST를 구성하는 스타일

  • client-server
  • stateless
  • cache
  • uniform interface 다른건 쉬운데 이 부분만 지키기 쉽지 않았다.
  • layerd system
  • code-on-demand(optional) _ 코드를 클라이언트로 보내서 실행시킬수 있어야 한다. ex)js

Uniform Interface의 제약조건

  • identification of resources (자원이 uri로 식별되어야 한다.)
  • manipulation of resources through representations (representations 전송을 통해서 자원을 조작해야 한다. 즉, http method를 통해서 자원을 조작해야 한다는 의미)
  • 여기까지는 대체로 만족하지만 아래의 사항은 그렇지 않다.
  • self-descriptive messages ()
  • hypermedia as the engine of application state (HATEOAS)

self-descriptive messages

메세지가 스스로 설명해야 한다. 메세지를 보고 온전한 해석이 가능해야 한다는 의미이다.

예시

이 HTTP 요청 메세지는 뭔가 빠져있어서 self-descriptive 하지 못하다. 아래 처럼 목적지를 추가해야 이제 self-descriptive한 요청이 된다.

그리고 또 생각해볼 것이 있다. 아래의 예시는 self-descriptive하지 못한 응답 메세지 이다.

이 상태로는 어떤 문법으로 작성되었는지 모르기 때문에 해석을 못한다. 그래서 아래와 같으 Content-Type 헤더가 추가가 되어야 한다. 이렇게 함으로써 []의 의미와, {}의 의미, 콜론으로 감싸진 문자열들의 의미가 무엇인지 알기 때문에 파싱이 가능해지고 문법을 해석할 수 있게되었다. 그렇다면 이제 self-descriptive하게 되었느냐? 아니다. 부족하다. 왜냐하면 이 응답을 해석하였다 해도 key값의 의미를 정확히 해석을 못하기 때문이다. 아래의 예시를 보자 위 처럼 Content Type 헤더에 application/json.patch +json라고 명시가 되어있는데 json.patch +json 라는 미디어타입으로 정의되어있는 메세지라는 의미이다. 이에 대한 명세를 찾아가서 이 메세지를 해석을 하면 그제야 이 메세지에 대한 옳바른 해석을 가능하게 된다. 이 처럼 이 하나의 응답으로 모든것을 해석이 가능해야 한다는 것.

HATEOS

HATEOS의 의미는 애플리케이션 상태는 Hyperlink를 이용해 전이되어야 한다는 의미

왜 Uniform Interface가 필요한가?

독립적 진화

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

  • 웹 페이지를 변경했다고 웹 브라우저를 업데이트 할 필요는 없다.
  • 웹 브라우저를 업데이트했다고 웹 페이지를 변경할 필요도 없다.
  • HTTP 명세가 변경되어도 웹은 잘 동작한다.
  • HTML 명세가 변경되어도 웹은 잘 동작한다.

간혹가다 모바일 환경에서 UI가 깨지는 경우도 있지만 페이지의 기능은 잘 된다. REST가 어느정도 만족되었기 때문이다. 그러나 모든 기종에 대한 호환성을 끝까지 지켜지지 못하는 경우가 있어 강제적 업데이트를 하는 경우가 생기는데 웹브라우저는 그런일이 생기지 않는다. 모바일의 경우는 엄밀히 말하면 REST 하지 않아서 그런거지만 말이다.

상호운용성(interoperability)에 대한 집착

  • Referer 오타인데 안고친다
  • charset 잘못 지은 이름이지만 안 고침
  • HTTP 상태코드 416 포기함
  • HTTP/0.9 아직도 지원함(크롬,파이어폭스)

HTTP/1.1의 공식 문서 발표가 있기 까지 7년이란 시간이 걸렸다. 모든 웹앱 어플리케이션이 HTTP/1.0 가이드를 따르고 있었기 떄문에 조금이라도 변경된 사항이 있으면 호환성에 큰 문제가 생기기 때문이다.

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

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

그럼 REST는 성공했는가?

네, 그렇습니다.

  • REST는 웹의 독립적 진화를 위해 만들어졌다.
  • 그리고 웹은 독립적으로 진화하고 있다.

그런데 REST API는?

  • REST API는 REST 아키텍쳐 스타일을 따라야한다.
  • 오늘날 스스로 REST API들의 대부분이 REST 아키텍쳐 스타일을 따르지 않는다.

REST API의 제약조건을 무조건 다 지켜하나..?

네 그렇습니다.
Roy T.Fielding는 다음과 같이 말했습니다.
"An API that provides network-based access to resources via a uniform interface of self-descriptive messages containing hypertext to indicate potential state transitions might be part of an overall system that is a RESTful application"

"하이퍼 텍스트를 포함한 self-descriptive한 메세지의 uniform interface를 통해 리소스에 접근하는 API는 RESTful application의 전부이다."

그리고 Roy T.Fielding 는 "원격 API가 꼭 REST API이어야 하는가" 에 대한 질문에 다음과 같이 답변했다.
"시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지 마라"

그럼 이제 어떻게 할까?

  1. REST API를 구현하고 REST API라 부른다.
  2. REST API 구현을 포기하고 HTTP API라고 부른다.
  3. REST API가 아니지만 REST API라고 부른다. (현재상태)

REST API를 구현해보도록 노력하자.

그럼 일단 왜 API는 REST가 잘 안되나.

흔한 웹페이와 HTTP API의 비교표이다. HTTP API는 모바일 같은 디바이스가 이해할 수있는 포맷, 즉 미디어타입을 사용한다. HTML에서는 a태그가 가능하고 각각의 a태그가 있다고 가정했을 시 각자의 목적에 대한 명세가 잘 표현되어 있지만 JSON 같은 경우에는 그렇지 않다. JSON은 문법 해석은 가능하지만, 의미를 해석하려면 별도의 문서(API 문서 등) 필요하다.

Self-descriptive 관점에서의 HTML vs JSON


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

  • Self-descriptive :: 확장 가능한 커뮤니케이션
    서버나 클라이언트가 변경되더라도 오고가는 메세지는 언제나 Self-descriptive 하므로 언제나 해석이 가능하다
  • HATEOAS :: 애플리케이션 상태 전이의 late binding
    어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.
    쉽게 말해서: 링크는 동적으로 변경될 수 있다.

그럼 REST API로 고쳐보자.

### 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 헤더(RFC 5988)와 profile(RFC 6906)을 이해해야 한다.
2. Content negotiation을 할 수 있다. 왜냐하면 미디어타입으로 판단 하는게 아니라 링크 헤더에 명시된 내용으로만 판단하기 때문이다.

HATEOAS

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

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

JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용한다.

  • JSON API
  • HAL
  • UBER
  • SIREN
  • Collection + json
  • ...

단점 : 기존의 API를 많이 수정해야 한다(침투적)

방법2:HTTP 헤더로 Link, Location 등의 헤더로 링크를 표현한다.

단점 : 정의된 relation만 활용한다면 표현에 한계가 있다.

data, 헤더 모두 활용하면 좋다.

Hyperlink는 반드시 uri여야 하는건 아닌가?

하이퍼 링크라는 표현만 되면 다 괜찮다.

Media type 등록은 필수인가?

NO, 아니다.

Roy. T.Fielding이 말하길..
"A REST API should be entered with no prior knowledge beyond the intitial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by ant client that might use the API)."

"만약 의도한 저자가 이해할수 있다면, 예를들어 회사 내부에서만 사용하는 API라면 그 사람들이 이 Media type을 이해 한다면 꼭 그럴필요는 없지만 권장한다. 하면 좋다"

Media type을 IANA에 등록하기

  • 누구나 쉽게 사용할 수 있게 된다.
  • 이름 충돌을 피할 수 있다.
  • 등록이 별로 어렵지 않다(고 주장)

정리

  • 오늘날 대부분 "REST API"는 사실 REST를 따르지 않고 있다.
  • REST의 제약조건 중에서 특히 Self-descriptive 와 HATEOAS를 잘 만족하지 못한다.
  • REST는 긴 시간에 걸쳐(수십년) 진화하는 웹 애플리케이션을 위한 것이다.
  • REST를 따를 것인지는 API를 설계하는 이들이 스스로 판단하여 결정해야 한다.
  • REST를 따르겠다면 Self-descriptive 와 HATEOAS를 만족시켜야한다.
    1. Self-descriptive는 custom media type이나 profile link relation 등으로 만족시킬수 있다.
    1. HATEOAS는 HTTP 헤더나 본문에 링크를 담아서 만족할 수 있다.
  • REST를 따르지 않겠다면, "REST를 만족하지 않은 REST API"를 뭐라고 부를지 결정해야 할 것이다.
    HTTP API라고 부를수도 있고
    그냥 이대로 REST API라고 부를 수도 있다.(roy가 극혐한다.)

참고

https://www.youtube.com/watch?v=RP_f5dMoHFc, 그런 REST API로 괜찮은가.

profile
Yanison's devlog

0개의 댓글