본문 바로가기
CS

REST, REST API 제데로 알아보자

by Ropung 2023. 10. 17.

그놈의 Rest, RestAPI, RestFull API …

  • 서버를 개발하고 회사의 JD(직무분석)를 분석하다보면, Rest 프로그래밍(설계) 이라는 단어를 자주 접하게 된다.
  • 블로그나 유튜브를 보며 REST를 정의 했을때, REST란 자원의 상태를 URL에 담아 표현하는 것이라고 생각했다.
  • 다른 개발자분들이 REST에 대해 정의를 해보라고 했을때 설명하기 난해하였고 설명이 진정한 REST가 맞냐는 말에 나는 대답을 하지 못했다.

모르겠다.jpeg
그래서 REST 이놈이 어떤것인지 정확히 정의하기 위해 REST를 파보기로 했다.


REST(REpresentational State Transfer)정의?

  • REST는 HTTP프로토콜을 그대로 활용하여 웹의 장점을 최대한 활용할 수 있는 아키텍처 원칙 세트이다.
  • 즉, 리소스를 이름으로 구분하여 해당 리소스의 정보를 주고 받는 모든 것을 의미한다고 한다.
a way of providing interoperability between computer systems on the Internet.
  • 인터넷상의 컴퓨터 시스템들간의 상호 운용성을 제공하는 방법

하지만, 이것만으로 설명하기는 난해하여 REST가 탄생한 배경을 살펴보자.

완벽히이해했어.jpg


REST의 탄생 배경

WEB(1991년)

팀버너스리.png

  • www(월드 와이드 웹)이 팀 버너스리(인물) 에 의해 탄생했을 때 인터넷을 통해 자료(정보)들을 공유할 때 어떻게 하면 잘할 수 있을까 고민하게 되었다.
  • 버너스리형은 정보들을 그 해답으로 하이퍼텍스트로 연결하여 제공했다.
    • HTML방식으로 정보를 표현하고, 정보들에 대한 식별자URI를 만들고
    • 이러한 정보들을 전송하기 위한 방법으로 HTTP라는 프로토콜을 만들었다.

HTTP / 1.0 (1994 - 1996년)

  • 버너스리형이 만든 HTTP라는 프로토콜을 여러사람들이 설계를 하게 되었다.
  • 1.0 명세가 나오기전에 이미 HTTPwww에 전송 프로토콜로 이용되고 있었다.

로이필딩.png

  • 당시 대학원생이였던 로이필딩(Roy Fielding)이 HTTP / 1.0 참여하게 되었다.
  • 웹은 급속도로 성장하는 과도기였고 이시기에 HTTP를 정립하고 기존의 기능을 고쳐야하는 상황이였다.
  • HTTP를 고치게 되면 기존 구축되어 있는 웹과 호환성에 문제가 생긴다.
  • 이 문제를 고민하던중 로이필딩은 HTTP Object Model 을 만든다.

REST(1998년)

  • HTTP Object Model가 4년후 REST라는 이름으로 Microsoft Research에서 발표되어 세계 최초로 공개가 된다.

REST(2000년)

  • 그 후 2년뒤 로이필딩(Roy Fielding)은 REST를 박사 논문으로 발표했다.
  • 이 논문이 오늘 날 우리가 말하는 REST이다.

프로토콜을 사용하는 API

API(Application Programming Interface)?

API는 프로그램들이 서로 상호작용하는 것을 도와주는 매개체로 볼 수 있다.


XML - RPC(1998년) -> SOAP

  • 원격으로 단일 시스템의 매서드를 호출할 수 있는 프로토콜을 Microsoft에서 만들었다.
  • 오늘 날 SOAP(Simple Object Access Protocol)이라는 이름의 프로콜이다.

Salesforce API(2000년 02월)

  • 최초의 공개된 API지만 인기가 너무 없었다.
  • 당시 SOAP을 사용해서 만들었는데 너무 복잡한 문제가 있었다.

[ 승부 ] SOAP API vs REST API

flickr API(2004년 8월)

  • SOAP, REST방법을 제공했는데 당시 REST가 SOAP에 비해 장점이 많았다.
SOAP REST
복잡 단순
규칙 많음 규칙 적음
어렵다 쉽다

REST API의 승리

  • SOAP은 갈수록 인기가 적어지고 REST는 인기가 많아진다.
  • 2006년, AWS가 자사 API의 사용량의 85%가 REST임을 밝힘.
  • 2010년, Salesforce.com도 REST API를 추가했다.

로이필딩: 아 그거 REST 아닌데…

CMIS(2008) 등장

  • CMS(콘텐츠 관리 시스템)를 위한 표준
  • EMS, IBM, Microsoft등이 함께 작업
  • REST 바인딩 지원

하지만 우리의 로이필딩형은…

놉짤.png
로이필딩: 아 그거 REST 아님 ㅋㅋ…

Microsoft Rest Api Guidelines 발표(2016년)

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

사람들은 이것이 합리적인 좋은 REST API에 부합한다고 생각했다.

하지만 이번에도 로이필딩형은…

놉짤.png
로이필딩: 아 그거 REST API 아님 ㅋㅋ HTTP API임ㅋㅋ
로이필딩: REST API를 위한 최고의 버저닝 전략은 버저닝 안하는거임ㅋㅋ


진정한 의미의 REST API 란?

REST API?

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

REST?

  • 분산 하이퍼미디어 시스템 (예: 웹)을 위한 아키텍쳐 스타일
  • 아키텍쳐 스타일이면서 동시에 하이브리드 아키텍쳐 스타일

아키텍쳐 스타일?

  • 제약조건의 집합
  • 이를 모두 지키는것이 REST

REST를 구성하는 스타일

대체로 대부분 지켜지지만 잘 안지켜지는것이 unifrom interface이다.

  • client-server
  • stateless
  • cache
  • uniform interface
  • layered system
  • code-on-demand(optional)
    • 서버에서 코드를 클라로 보내서 실행할 수 있어야한다.
    • 자바스크립트를 의미

Uniform Interface가 뭐길래…?

지켜지고 있는 제약조건

  • 리소스가 uri로 식별되면 된다.
    (identification of resources)
  • 자원을 CUD할 때, uri에 표현을 담아서 전송하면 된다.
    (manipulation of resources through representations

잘 안지켜지는 제약조건(로이형 스위치)

  • 메세지는 스스로를 설명해야 한다.
    (Self-descriptive message)
  • 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.
    (HATEOAS)

잘 지켜지지 않는 제약조건 예시를 보자

Self-descriptive message 예시

  • 메세지는 스스로를 설명해야 한다.

예시) HTTP 요청 메세지

//[틀린예시]: 목적지가 빠져있으면 self-descriptive 하지않다.
GET / HTTP/1.1

//[옳은예시]: 목적지를 추가하면 self-descriptive 하게된다.
GET / HTTP/1.1
HOST: www.example.org

예시) HTTP 응답 메세지

//[틀린예시1]:  self-descriptive 하지않다.
HTTP/1.1 200 OK
[{ "op":"remove", "path":"/a/b/c"}] - 어떤 문법인지 모름

//[틀린예시2]:  self-descriptive 하지않다.
HTTP/1.1 200 OK
// 문법이 해석가능해 지지만 op, path가 무엇을 의미하는지 모름 
Content-Type: application/json
[{ "op":"remove", "path":"/a/b/c"}]

//[옳은예시]:  self-descriptive 하게된다.
HTTP/1.1 200 
// 문법해석도 가능하고 op, path가 무엇을 의미하는지 미디어 정보가 json-patch+json으로 나타남
Content-Type: application/json-patch+json 
[{ "op":"remove", "path":"/a/b/c"}]

HATEOAS를 만족한 예시

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

예시) 태그를 통한 방법

  • <a태그>를 통해서 하이퍼링크가 나타나있고 이를 통해 하이퍼링크를 충족하여 전이
HTTP/1.1 200 OK
<html>
<head></head>
<body><a href="/test">test</a></body>
</html>

예시) Json에 나타나있는 Link

  • Link를 통해 다른 리소스를 가르킬수 있고 하이퍼링크를 타서 정보를 제공
HTTP/1.1 200 OK
Content-Type: application/json
Link: </test/1>; rel="previous",
	  </test/3>; rel="next";

{json example...}

그래 쓰는방법은 대충 알겠어 근데 Uniform Interface를 지켜야해?

진화.png

독립적 진화

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

REST를 만들게 된 계기

  • 어떻게 하면 기존 웹 HTTP를 깨뜨리지 않을수 있을까를 고민한 로이형의 고민의 산물
    (How do I improve HTTP without breaking the Web?)

오늘 날 편하게 쓰는 웹

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

반면 앱은?

  • 업데이트 마다 동작에 문제가 생긴다.
  • REST하지않기 떄문이다.

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

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

하위 호환성을 지키기 위한 노력(피땀눈물)

  • HTML5 첫 초안에서 권고안 나오는데까지 6년
  • HTTP/1.1 명세 개정판 작업하는데 7년

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

???: 아 그거 어짜피 고쳐봤자 중요한것도아니고 고치면 웹 아예 안되는데 냅둬~

  • Referer 오타지만 안고침
  • charset 잘못 지은 이름이지만 안 고침
  • HTTP 상태 코드 416 포기함(I’m a teapot)
  • HTTP/0.9 아직 지원(크롬, 파이어폭스)

이를 고치는 순간 웹은 지옥으로…

REST는 성공?

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

다시 돌아와서 오늘날의 REST API는?

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

로이형 API가 꼭 REST API여야 해요?

놉짤.png
로이필딩: 시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지 마라.
로이필딩: 제발… 제약조건을(저작권) 따르던지 아니면 HTTP API 같은 다른 단어를 써라.

오늘날의 API는 REST가 잘 안되는 이유?

일반적인 웹과 비교해보자.

HTML HTTP API
프로토콜 HTTP HTTP
커뮤니케이션 사람-기계 기계-기계
Media Type HTML JSON

HTML vs JSON

HTML JSON
Hyperlink ㅇ(a태그 등…) x
Self-descriptive ㅇ(HTML 명세) 불완전
  • 문법 해석은 가능하지만, 의미를 해석하려면 별도로 문서가(API 문서 등) 필요하다.

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

Self-descriptive 확장 가능한 커뮤니케이션

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

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

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

가짜 REST API를 진짜 Rest API으로 만드는 방법

Self-descriptive: Media type 방법

  • 미디어 타입을 하나 정의한다.
  • 미티어 타입 문서를 작성한다
    (이 문서에 "id"가 뭐고 "title"이 뭔지 의미를 정의한다.)
  • IANA에 미디어 타입을 등록한다.
    (이 때 만든 문서를 미티어 타입의 명세로 등록한다.)
  • 이제 이 메세지를 보는 사람은 명세를 찾아갈 수 있으므로 이 메세지의 의미를 온전히 해석할 수 있다.
GET ...
HOST:...

HTTP ...
// 미디어 타입을 정해주고 키의 의미를 정의한다.
Content-Type: application/vnd.todos+json
[
	{"id":1, "title":"회사 가기"},
	{"id":1, "title":"회사 가기"}
]

Media type 등록은 필수인가?

놉짤.png
로이필딩: 하지만 하면 좋다 난 쉽던데?

Media type 단점

  • 매번 media type을 정의해야 한다.

Self-descriptive: Profile 방법

  • "id", "title"의 의미를 정의한 명세를 작성한다.
  • Link 헤더에 profile relation으로 해당 명세를 링크한다.
  • 메세지를 보는 사람은 명세를 찾아갈 수 있으므로 이 문서의 의미를 온전히 해석할 수 있다.
GET ...
HOST:...

HTTP ...
Content-Type: application/json
// profile relation으로 해당 명세를 링크
Link: <https://example.org/docs/todos>; rel="profile"
[
	{"id":1, "title":"회사 가기"},
	{"id":1, "title":"회사 가기"}
]

Profile 단점

  • 클라이언트가 Link 헤더(RFC 5988)와 profile(RFC 6906)을 이해해야 한다.
  • Content negotiation을 할 수 없다.

Content negotiation(콘텐츠 협상)??

  • 웹 브라우저(user-agent)가 이용자에게 알맞은 형태의 리소스를 받을 수 있도록, 리소스를 어떤 형태로 받을지 정하는 메커니즘을 일컫는다. 이때 리소스의 형태는 문서의 언어나 이미지 포맷, 인코딩 등을 말한다.

HATEOAS: data로 표현하는 방법

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

HTTP ...
Content-Type: application/json
// profile relation으로 해당 명세를 링크
Link: <https://example.org/docs/todos>; rel="profile"
[
	{
		//data에 다양한 방법으로 하이퍼링크를 표현한다.
		"link":"http://example.org/todos/1",
		"title":"회사 가기"
	},
	{
		"link":"http://example.org/todos/1,
		"title":"회사 가기"
	}
]

data표현 단점

  • 링크를 표현하는 방법을 직접 정의해야한다
  • 기존 API를 많이 고쳐야한다.(침투적)

HATEOAS: HTTP 헤더로 표현하는 방법

  • Link, Location 등의 헤더로 링크를 표현한다.
POST ...
Content-Type: application/json
{
	"title":"제목"
}
HTTP/1.1 204 No Content
// Link, Location 등의 헤더로 링크를 표현한다.
Location: /todos/1
Link: </todos/>; rel="collection"

HTTP 헤더표현 단점

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

마무리 정리

  • 오늘날 대부분의 "REST API"는 사실 REST를 따르지 않고 있다.
    (로이: 그러니 가짜다.)
  • REST의 제약조건 중에서 특히 Self-Descriptive와 HATEOAS를 잘 만족하지 못한다.
  • REST는 긴 시간에 걸쳐(수십년) 독립적으로 진화하는 웹 애플리케이션을 위한 것이다.
  • REST를 따르겠다면, Self-descriptive와 HATEOAS를 만족시켜야 한다.
  • REST를 따르지 않겠다면, REST를 만족하지 않는 REST API를 뭐라고 부를지 정해야 할 것이다.
    • HTTP API라던가 그냥 REST API라고 부를 수도있지만 로이필딩이 싫어할 것이다.

참고자료

HTTP 콘텐츠 협상
유튜브 - 그런 REST API로 괜찮은가
벨로그 - 진정한 RestFull API
REST,REST API, REST FULL API

'CS' 카테고리의 다른 글

로드밸런서(Load Balancer)란?  (0) 2023.10.13
동기와 비동기  (0) 2023.10.13
프로세스 스레드  (0) 2023.10.13
AXIOS가 뭐하는 녀석인지? - 비동기 통신, Promise, Ajax, HTTP,  (0) 2023.02.16