Rest API를 사용한 프로젝트를 끝냈지만 그래서 Rest API가 뭔데요? 사용 이유는 무엇인가요? 라고 물었을 때
시스템 간 데이터를 교환할 때 자원으로 나타내는 URI를 사용한 이동 규칙이라는 말 말고는 청산유수하게 설명할 수 없었습니다.
정보를 찾던 중 DEVIEW 2017 이응준님의 '그런 Rest API로 괜찮은가' 라는 좋은 영상이 있어 들으며 정리를 해보려고 합니다.
※ Project에 바로 적용할 수 있는 Rest API 설명 글이 아닌 REST에 대하여 탐구하는 글입니다!※
REST
컴퓨터 시스템간의 상호 운용성을 제공하기 위한 방법중 하나이다 -> 무슨 소리인지 모르겠으니 더 알아보자
Rest API 탄생배경
탄생배경을 알기 위해 WEB의 역사부터 알아야한다!
팀 버너스리 -> World Wide Web 하이퍼텍스트 시스템을 개발한 컴퓨터 과학자
Question : 인터넷에서 정보를 어떻게 공유할 것인가?
Answer : 정보들을 하이퍼텍스트로 연결한다.
표현형식 : HTML
식별자 : URI
전송 방법 : HTTP
Roy T.Fielding의 REST
어떻게 Web을 망가뜨리지 않고 HTTP를 개선할 수 있을까?
-> HTTP Object Model -> REST(1998) 발표 -> REST(2000) 박사 논문으로 발표
논문 링크 : https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
SOAP(Simple Object Access Protocol) VS REST
SOAP | REST |
복잡하다 | 단순하다 |
규칙 많음 | 규칙 적음 |
어렵다 | 쉽다 |
2016년에 Microsoft가 REST API 에 대하여 가이드라인을 발표했으나 Roy T.Fielding은 Rest API가 아니다. 이건 HTTP API 이다. 라고 말하였다.
사람들이 이해하고 있던 REST와 Roy T.Fielding의 REST가 달랐다.
REST에 대하여 따져보자
REST API
REST 아키텍처 스타일을 따르는 API
'REST' in the Roy T.Fielding dissertation
분산 하이퍼미디어 시스템(ex.web)을 위한 아키텍처 스타일
아키텍처 스타일이란?
제약조건의 집합
따라서 제약조건을 모두 따라야 'REST를 따른다' 라고 말할 수 있다.
REST는 아키텍처 스타일이면서 동시에 하이브리드 아키텍처 스타일이다.
REST를 구성하는 스타일
- client-server
- stateles
- cache
- uniform interface -> 잘 만족을 못한다 이것에 대해서 집중적으로 알아보자!
- layered system
- code-on-demand(optional) -> JavaScript
Uniform Interface의 제약조건
- identification of resources(자원이 URI로 식별된다)
- manipulation of resoruces through representations(representations 전송을 통해 resources를 조작)
- self-descriptive messages
- hypermeda as the engine of application state(HATEOAS)
밑의 2가지는 거의 지켜지지 않는다고 보면 된다.
Self-descriptive message
메세지만 보고 알 수 있어야한다.
HTTP/1.1 200 OK
Content-Type: application/json-patch+json //json-patch+json과 같은 미디어타입을 알려줘야한다
[ { "op": "remove", "path": "/a/b/c" } ]
HATEOAS
애플리케이션의 상태는 Hyperlink를 이용해 전이되어야한다.
글 목록 보기 -> 글쓰기 -> 글 저장 -> 글 보기 -> 글 목록보기 ...
HTTP/1.1 200 OK
Content-Type: application/json
Link: </articles/1>; rel="previous", //이전 링크
</articles/3>; rel="next"; //이후 링크
{
"title": "The second article",
"contents": "blah blah"
}
Uniform Interface는 왜 필요한가?
독립적 진화를 위해서이다.
- 서버와 클라이언트가 각각 독립적으로 진화한다
- 서버의 기능이 변경되어도 클라이언트를 업데이트할 필요가 없다.
-> 서버가 기능이 바뀌어도(URI가 바뀌거나 기능이 추가되거나 삭제되어도) 클라이언트가 업데이트할 필요가 없다.
REST가 지켜지고 있는 사례 WEB
- 웹 페이지를 변경했다고 웹 브라우저를 업데이트할 필요는 없다.
- 웹 브라우저를 업데이트했다고 웹 페이지를 변경할 필요도 없다.
- HTTP 명세가 변경되어도 웹은 잘 동작한다.
- HTML 명세가 변경되어도 웹은 잘 동작한다.
모바일은 Rest Architecture style을 따르고 있지 않아서 업데이트 하지 않을 시 호환성의 문제가 생긴다.
Web은 어떻게 이렇게 발전할 수 있었을까?
- HTML5 첫 초안에서 권고안까지 6년
- HTTP/1.1 명세 개정판 작업 7년 - 기능이 추가된것도 아닌데 왜 이렇게 오래걸렸나? : 하위 호환성을 깨뜨리면 안되기 때문에
상호운용성(interoperability)에 대한 집착
- Referer 오타지만 안 고침 -> 고치는 순간 Web이 깨질 수 있다.
- charset 잘못 지은 이름이지만 안 고침
- HTTP 상태 코드 416 포기함('I'm a teapot) - 이미 다른 곳에서 사용을 한듯하다...!! 영구 결번..!
- HTTP/0.9 아직도 지원함(크롬, 파이어폭스) - 지원안하면 어디선가 오류난다!
대단하다 대단해......
REST가 웹의 독립적 진화에 도움을 주었나
- HTTP에 지속적으로 영향을 줌
- Host 헤더 추가
- 길이 제한을 다루는 방법이 명시(414 URI Too Long 등)
- URI에서 리소스의 정의가 추상적으로 변경됨: "식별하고자 하는 무언가"
- 기타 HTTP와 URI에 많은 영향을 줌
- HTTP/1.1 명세 최신판에서 REST에 대한 언급이 들어감
- Reminder: Roy T.Fielding이 HTTP와 URI 명세의 저자 중 한명이다
REST는 성공했는가?
- REST는 웹의 독립적 진화를 위해 만들어졌다
- 웹은 독립적으로 진화하고 있다
= 성공했다
REST API는?
- REST API는 REST 아키텍처 스타일을 따라야한다.
- 오늘날 스스로 REST API라고 하는 API들의 대부분이 REST 아키텍처 스타일을 따르지 않는다.
REST API도 저 제약조건을 다 지켜야하는가?
Answer : 지켜야한다
어떨 때 REST API를 지키지 않아도 되는가?
시스템 전체를 통제할 수 있다 -> server 개발, client를 한번에 만들어서 완전 통제 가능한 경우
진화에 관심이 없다 -> REST에 대하여 알고 싶지 않다, 오랜시간 발전을 할 필요가 없는 경우
현재 상태
REST API가 아니지만 REST API라고 부른다.
-> 👨Roy T.Fielding : Please try to adhere to them or choose some other buzzword for your API.
제약조건을 따르거나 너의 API에 다른 단어를 사용해라. REST 붙이지마
API는 왜 REST가 잘 안되는가?
웹페이지와 비교해보자
Web Page | HTTP API | |
Protocol | HTTP | HTTP |
Communication | 사람-기계 | 기계-기계 |
Media-Type | HTML | JSON |
HTML | JSON | |
Hyperlink | 됨(a 태그 등) | 정의되어있지 않음 |
Self-descriptive | 됨(HTML 명세) | 불완전(Object에 대한 공용적인 정의가 없다) |
문법 해석은 가능하지만, 의미를 해석하려면 별도로 문서가(API 문서) 필요하다.
Self-descriptive와 HATEOAS가 독립적 진화에 어떻게 도움이 될까?
Self-descriptive
확장 가능한 커뮤니케이션을 가능하게한다.
서버나 클라이언트가 변경되더라도 오고가는 메세지는 언제나 self-descriptive 하므로 언제나 해석이 가능하다.
HATEOAS
애플리케이션 상태 전이의 late binding
어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.
->링크는 동적으로 변경될 수 있다. 언제나 마음대로 바꿀 수 있다!
그래서 json 형태의 API 통신을 어떻게 하면 Self-descriptive가 될까?
방법 1
1. 미디어 타입을 하나 정의한다.
2. 미디어 타입 문서를 작성한다.(사용한 프로퍼티의 명세를 작성)
3. IANA에 미디어 타입을 등록한다.
4. 명세를 찾아갈 수 있으므로 이 메시지의 의미를 온전히 해석할 수 있다.
Media type 등록 필수인가?
아니다.
의도한 저자가 이해할 수만 있으면 상관없다. ex) 회사 내에서만 쓰는 API여서 모두 이해를 할 수 있는 상황
방법 2
1. 프로퍼티의 의미를 정의한 명세를 작성한다.
2. Link 헤더에 profile relation으로 해당 명세를 링크한다.
3. 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 문서의 의미를 온전히 해석할 수 있다.
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
Link: <http://example.org/docs/todos>; rel="profile"
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
단점
1. 클라이언트가 Link 헤더(RFC 5988 링크:https://www.rfc-editor.org/rfc/rfc5988)와 profile(RFC 6906 링크: https://www.rfc-editor.org/rfc/rfc6906)을 이해해야한다.
2. Content negotiation을 할 수 없다.
json HATEOAS
방법1 : data로
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
Link: <http://example.org/docs/todos>; rel="profile"
[
{"link": "http://example.org/todos/1", "title": "회사 가기"},
{"link": "http://example.org/todos/2", "title": "집에 가기"}
]
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
Link: <http://example.org/docs/todos>; rel="profile"
{
"links": {"todo": "http://example.org/todos/{id}"},
"data" : [
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
}
단점
링크를 표현하는 방법을 직접 정의해야한다 -> self-descriptive
방법2 : HTTP 헤더로
Link, Location 등의 헤더로 링크를 표현한다.
POST /todos HTTP/1.1
Content-Type: application/json
{
"title": "점심 약속"
}
HTTP/1.1 204 No Content
Location: /todos/1
Link: </todos/>; rel="collection"
단점
정의된 relation만 활용한다면 표현에 한계가 있다.
정리
- 오늘날 대부분의 "REST API"는 사실 REST를 따르지 않고 있다.
- REST의 제약조건 중에서 특히 Self-descriptive와 HATEOAS를 잘 만족하지 못한다.
- REST는 긴 시간에 걸쳐(수십년) 진화하는 웹 애플리케이션을 위한 것이다.
- REST를 따를 것인지는 API를 설계하는 이들이 스스로 판단하여 결정해야한다.
- REST를 따르겠다면 Self-descriptive와 HATEOAS 를 만족시켜야한다.
- REST를 따르지 않겠다면, "REST를 만족하지 않는 REST API"를 뭐라고 부를지 결정해야 할 것이다.
영상 후기
그저 resources 단위를 활용한 client와 server의 데이터 통신을 해보자! 라는 마음으로 프로젝트에 적용을 해왔다면 이 영상을 보고 많은 생각이 들었네요...
지금까지 Web의 발전과 거기에 투자한 개발자님들의 노고를 생각하면 REST API를 사용한다는 말을 쉽게하면 안될거같습니다... 정진 또 정진해야겠다는 생각이 드네요. 정말 좋은 영상입니다!!!
링크 : https://tv.naver.com/v/2292653
Day1, 2-2. 그런 REST API로 괜찮은가
NAVER Engineering
tv.naver.com
'Network' 카테고리의 다른 글
웹소켓(Web Socket)이란? (3) | 2024.10.21 |
---|---|
[Network] SMTP (1) | 2022.12.07 |
[인프런] HTTP 웹 기본 지식 (1) | 2022.12.07 |
MIME(Multipurpose Internet Mail Extensions) 타입 (0) | 2022.10.30 |