그런 REST API로 괜찮은가? 본 내용은 위 유투브를 바탕으로 정리한 내용이며, 영상을 보는 겻을 추천한다. 또한, 구글링을 하면 RESTful API에 대해 더 자세히 나온 자료들도 많으니 한번쯤은 다른 자료들도 검색하면서 보면 더욱 이해가 잘 될 것이다.
프로그램 개발을 공부하면서 REST API라는 단어는 자주 들었는데, API라는건 알겠는데 REST는 정확히 어떤것을 뜻하는지 잘 몰랐기에 위 유투브 영상과 다른 사이트들을 참고함.
REST란?
컴퓨터 시스템간의 상호운영성을 제공하는 것 중에 하나
REST의 역사(유래)
www(World Wide Web)이 나왔을 때 정보를 공유해야 하는데, 어떻게 하면 잘 할수 있을까 라는 고민을 시작으로 모든 정보들을 하이퍼텍스트로 연결하기로 하여 아래와 같은 통신규약을 만들었다.
표현 형식: HTML(Hyper Text Markup Language) - TCP/IP기반 식별자: URI(Uniform Resource Identifier) - 인터넷에 있는 자원을 나타내는 유일한 주소(고유한 주소)
- URL과의 차이점: URL은 자원(파일)의 위치(구체적인 주소)를 알려주기 위한 규약이다. 흔히 웹사이트 주소로 알고 있지만, URL은 주소뿐만 아니라 컴퓨터 네트워크상의 자원을 모두 나타낼 수 있다. 전송방법: HTTP(프로토콜)
-
하이퍼텍스트 문서를 교환하기 위해 만들어진 통신규약
- request/response 구조로 되어 있고, stateless형태(여러 요청과 응답에 대해 연결되어 있지 않다.)
- Method(GET,POST 등)
- Request target(ex: /login)
- HTTP Version
당시 대학생이었던 로이필딩(REST 창시자)이 HTTP 1.0 작업에 참여하였고, 호환성 문제를 부딪혔는데 어떻게 하면 웹을 망가트리지 않고, HTTP를 증폭시킬 수 있을까라는 고민을 시작하여 HTTP Object model이라는 것을 만들었고, 이 모델이 현재의 REST로 불리게 되었다.
API
마이크로소프트가 XML-RPC 원격으로 다른 시스템의 메소드를 호출할 수 있는 SOAP
라는 프로토콜을 만들었고, salesforce라는 사이트에서 2000년 2월에 최초로 API를 SOAP을 사용해서 공개했다. 하지만 코드가 복잡하여 사용하기가 쉽지 않아서 인기가 없었다고 한다.
salesforce의 SOAP API
얼마 후 flickr라는 미국 온라인 사진공유 커뮤니티 사이트에서 SOAP과 REST로 된 2가지의 API를 공개했다.
SOAP | REST |
---|---|
복잡하다 | 단순하다. |
규칙이 많다 | 규칙적음 |
어렵다 | 쉽다 |
이때까지만 해도 SOAP에 비해 REST의 코드가 단순하여 결국 SOAP은 하락하고, REST가 급상승하게 되었다.
What is REST API?
로이필딩에 의하면 REST API는 버저닝을 하지 않는게 최고의 버저닝이라고 얘기하였고,
REST API란 REST 아키텍처 스타일을 따르는 API이고,
REST란 분산 하이퍼 미디어 시스템을 위한 아키텍쳐 스타일이며,
아키텍쳐 스타일이란 제약조건의 집합이라고 설명한다.
(로이필딩의 논문에 쓰인 모든 제약조건을 지켜야 REST를 따른다고 설명함)
REST를 구성하는 스타일(아키텍쳐스타일)은 다음과 같다
- client-server
REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성이 줄어들게 됩니다. - stateless
REST는 무상태성 성격을 갖습니다. 다시 말해 작업을 위한 상태정보를 따로 저장하고 관리하지 않습니다. 세션 정보나 쿠키정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 됩니다. 때문에 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해집니다. - cache
REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹표준을 그대로 사용하기 때문에, 웹에서 사용하는 기존 인프라를 그대로 활용이 가능합니다. 따라서 HTTP가 가진 캐싱 기능이 적용 가능합니다. HTTP 프로토콜 표준에서 사용하는 Last-Modified태그나 E-Tag를 이용하면 캐싱 구현이 가능합니다. -
uniform interface
Resource(URI)에 대한 요청을 통일되고, 한정적으로 수행하는 아키텍처 스타일을 의미하며, 이것은 요청을 하는 Client가 플랫폼(Android, Ios, Jsp 등)에 무관하며, 특정 언어나 기술에 종속받지 않는 특징을 의미한다. 이러한 특징 덕분에 Rest API는 HTTP를 사용하는 모든 플랫폼에서 요청가능하며, Loosely Coupling(느슨한 결함) 형태를 갖게 되었습니다.(다른 조건은 웹 통신을 하게 되면 모두 잘 지켜지지만, uniform interface의 조건을 모두 충족하는게 쉽지 않다고 함)- identification of resources
- manipulation of resources through representations
- self-descriptive messages
- hypermedia as the engine of application state (HATEOAS)
uniform interface
uniform interface가 필요한 이유
서버와 클라이언트가 각각의 독립적인 진화를 하기 위해서 필요함
서버와 클라이언트가 독립적이어야 한다. 왜냐하면 서버의 기능이 수정되어(API변경(추가, 수정 삭제), URI변경 등 ) 클라이언트는 문제없이 돌아가야 한다. 만약 서버의 기능이 수정되어 클라이언트도 바꿔야 한다면 동시에 업데이트를
-
identification of resources: 리소스가 URI로 식별되면 된다.
- 일반적으로 리소스란, 사용될 수 있는 어떤 항목을 말한다. 프린터나 디스크 드라이브와 같은 장치들이 리소스가 될 수 있으며, 메모리도 마찬가지이다. 여기서 말하는 리소스는 HTTP 요청 대상을 얘기하며, 사진, 문서, 또는 다른 어떤 것이든 될 수 있다.
웹 리소스 식별(MDN
- 일반적으로 리소스란, 사용될 수 있는 어떤 항목을 말한다. 프린터나 디스크 드라이브와 같은 장치들이 리소스가 될 수 있으며, 메모리도 마찬가지이다. 여기서 말하는 리소스는 HTTP 요청 대상을 얘기하며, 사진, 문서, 또는 다른 어떤 것이든 될 수 있다.
- manipulation of resources through representations(표현을 통한 자원 조작(구글번역) : 리소스를 만들거나 업데이트 하거나 삭제할 때 HTTP 메세지에 표현을 담아서 전송을 통해서 달성하면(조작하면) 된다.
-
self-descriptive messages : 메세지는 스스로를 설명해야 한다. > 예를 들어
GET / HTTP/1.1
이라는 요청메세지가 있다면,GET / HTTP/1.1 Host: www.example.org
목적지를 추가해야 self-descriptive를 지킨다고 할 수 있다. 또한,
HTTP/1.1 200 OK [ { "op": "remove", "path": "a/b/c"} ]
일 때, 어떤 문법으로 작성되어 있는 건지 모르기 때문에 REST API라 부를 수 없으며, 아래와 같이 출력되어야 한다.
HTTP/1.1 200 OK Content-Type: application/json/json-patch+json # 미디어 타입의 json [ { "op": "remove", "path": "a/b/c"} ]
어떤 타입인지 명시를 해줘야 한다.
메세지를 봤을 때 메세지의 내용으로 온전히 해석이 가능해야 한다. 하지만 오늘날에는 잘 못지켜지고 있음
- hypermedia as the engine of application state (HATEOAS)
현재의 URI에서 다음 URI를 명세했는지?(표현된 링크를 통해 다음 상태로 전이될 수 있는지를 보고 만족유무를 판단)
클라이언트를 개발하는 사람들이 특정 메소드로부터 올 수 있는 결과 동작에 대해 예측하는 것이 가능해지고, API가 변경되더라도 키가 바뀌지 않는 한 URI로 주어진 링크(link)만 유지하면 되므로 별도의 대응이 요구되지 않게 된다는 것, 즉 클라이언트가 제공되는 API의 변화에 일일이 대응하지 않아도 되는 엄청난 편리함을 제공 - layered system
REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 합니다. - code-on-demand(optional)
서버에서 코드를 클라이언트에게 보내서 실행할 수 있어야 함 (JAVASCRIPT)
웹 애플리케이션에서는 REST API라고 부를 수 있을 만큼 잘 지켜지고 있지만, 모바일 앱 애플리케이션은 잘 안지켜지고 있다고 한다.
웹은,
- 웹 페이지를 변경했다고 웹 브라우저를 업데이트할 필요는 없다.
- 웹 브라우저를 업데이트했다고 웹 페이지를 변경할 필요도 없다.
- HTTP 명세가 변경되어도 웹은 잘 작동한다.
- HTML 명세가 변경되어도 웹은 잘 작동한다.
모바일 웹은 문제를 업데이트를 하면 문제가 되고 있음, 서버가 기능을 변경했는데, 클라이언트가 호환성을 지원해주는게 한계가 있고, 이 같은 문제들로 인해 클라이언트와 서버의 독립성을 잘 지키지 못하고 있어 문제가 되는 듯 하다.
즉, REST API 를 따르고 있지 않다고 보면 됨
결론: 웹은 이런 일이 거의 없지만 모바일 웹에서는 잦은 일이다.
웹이 잘 작동하는 이유는 아래와 같다.
- 상호운용성(interoperability)에 대한 집착
- 버전업이 아닌 문서를 수정하고 보완하는데도 많은 시간을 소비(10년 정도)하고, 하위 호환을 하기 위해 수많은 개발자 들이 머리를 싸매고 꾸준한 노력을 하기 때문임
- 하위호환: 예를 들어 현재 Rederer, charset은 오타가 나서 잘못 붙여진 이름이지만 수정하게 되면 상호운영성이 깨지기 때문에 아직까지도 수정되고 있지 않다.
REST가 웹의 독립적 진화에 도음을 주었는가??
-
HTTP에 지속적으로 영향을 줌
- Host 헤더 추가
- 길이 제한을 다루는 방법이 명시
- URI에서 리소스의 정의가 추상적으로 변경됨: “식별하고자 하는 무언가” > 예전에는 문서의 위치가 정의되었었음
- 기타 HTTP와 URI에 많은 영향을 줌
- HTTP/1.1 명세 최신판에서 REST에 대한 언급이 들어감
REST가 성공했는가?
- REST는 웹의 독립적 진화를 위해 만들어졌다.
-
웹은 독립적으로 진화하고 있다.
성공!!
REST API는?
- REST API는 REST 아키텍쳐 스타일을 따라야 한다.
- 오늘날 스스로 REST API라고 하는 API들의 대부분이 REST 아키텍쳐 스타일을 따르지 않는다.
제약 조건을 모두 지켜야 하는가?
- 로이필드가 제약조건을 모두 지켜야 한다고 명시를 함
꼭 REST API여야 하는건가?
-
로이필드가 아니여도 상관없다고 한다.
시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지 마라
시스템 전체를 통제: 서버개발자가 클라이언트를 통제하거나, 혼자 모두 다 만들 수 있을 때 진화에 관심이 없다는 것: 잦은 업데이트로 문제가 생겼다는 것을 듣고도 상관없다면,,
어떻게 해야 할까?
- REST API를 구현하고 REST API라고 부른다.
- REST API 구현을 포기하고 HTTP API라고 부른다.
- REST API가 아니지만 REST API라고 부른다.(현재)
웹은 잘 되는데 API는 왜 문제가 되는지??
-
HTML과 JSON의 차이에 대해 알아야한다.
- 문법 해석은 가능하지만 의미를 해석하려면 별도로 문서가(API문서 등) 필요하다.
HTML의 경우
#예시
GET / todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type : text/html
<html>
<body>
<a href="https://todos/1"> 회사 가기</a>
<a href="https://todos/2"> 집에 가기</a>
<body>
<html>
Self-descriptive = 모든 태그의 해석방법이 구체적으로 나와 있고, 힌트만을 단서로 해석할 수 있음 SUCCESS
HATEOAS = a태그를 통해 다음 전이될 페이지를 명시함 SUCCESS
JSON의 경우
GET / todos HTTP/1.1
Host:L exampele.org
HTTP/1.1 200 OK
Content-Type: application/json
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"},
]
Self-descriptive = id가 무엇을 의미하는지, title이 무엇을 의미하는지 알 방법이 없음 FAIL HATEOAS = 다음으로 전이될 페이지가 명시되어 있지 않다 FAIL
과연 두가지의 제약조건(self-descriptive, HATEOAS)가 독립적인 진화에 어떻게 도움이 될까?
Self-descriptive: 확장 가능한 커뮤니케이션
서버나 클라이언트가 변경되더라도 오고가는 메세지는 언제나 해석이 가능하다
HATEOAS : 애플리케이션 상태 전이의 late binding
링크들을 동적(마음대로) 바꿀 수 있고, 서버가 바꿔도 클라이언트의 동작은 전혀 문제가 없다.
JSON을 수정해서 REST API로 할 경우
GET / todos HTTP/1.1
Host: exampele.org
HTTP/1.1 200 OK
Content-Type: application/json
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"},
]
Self-descriptive
-
Content-Type: application/vnd/todos+json으로 수정 후 IANA에 내용 등록
매번 media type을 정의해야 한다.
-
headers에
Link: <https://example.org/docs/todos>; rel="profile"
을 명시하고, id가 어떤건지 명시하는 문서를 하나 작성한다.클라이언트가 link헤더와 프로필을 이해해야 한다. Content negotiation을 할 수 없다.
HATEOAS
본문에 링크를 추가해서 보내기 > 링크표현 방법을 직접 정의해야 한다.(링크헤더에서 프로필을 정리, 문서에 정의) 데이터에 다양한 방법으로 하이퍼링크를 표현 > JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용 > 기존 API를 많이 고쳐야 함(침투적)
data, headers를 통해 활용해서 표현할 수 있다.
RESTful이란
RESTful은 일반적으로 REST라는 아키텍처를 구현하는 웹 서비스를 나타내기 위해 사용되는 용어이다. ‘REST API’를 제공하는 웹 서비스를 ‘RESTful’하다고 할 수 있다. RESTful은 REST를 REST답게 쓰기 위한 방법으로, 누군가가 공식적으로 발표한 것이 아니다. 즉, REST 원리를 따르는 시스템은 RESTful이란 용어로 지칭된다.
- RESTful의 목적
이해하기 쉽고 사용하기 쉬운 REST API를 만드는 것 RESTful한 API를 구현하는 근본적인 목적이 성능 향상에 있는 것이 아니라 일관적인 컨벤션을 통한 API의 이해도 및 호환성을 높이는 것이 주 동기이니, 성능이 중요한 상황에서는 굳이 RESTful한 API를 구현할 필요는 없다. - RESTful 하지 못한 경우
Ex1) CRUD 기능을 모두 POST로만 처리하는 API Ex2) route에 resource, id 외의 정보가 들어가는 경우(/students/updateName) https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
정리
오늘날 REST API는 사실 REST를 많이 따르지 않는다고 하며, 이유는 REST의 제약조건 중 Self-descriptive와 HATEOAS를 만족하지 못하는 사례가 제일 많다고 한다. REST는 긴 시간에 걸쳐 진화하는 웹 애플리케이션을 위한 것이다. 따를 것인지 스스로 판단하여 결정해야 한다.
- Self-descriptive와 HATEOAS를 만족시켜야 함
따르지 않을 경우 어떻게 부를것인지??