-
[REST tutorial] REST? REST API? RESTful? REST에 대한 아주 쉬운 개념 정리!Computer Science 2019. 9. 16. 10:00
Ajax에 관해 공부할때 REST라는 단어를 한번쯤을 들어봤을 것이다.
여기저기에 굉장히 자주 쓰이는 단어인데 문제는 REST가 그래서 뭔데? 라고 말했을때 설명하기 굉장히 어렵다는 것이다.
그래서 오늘은 REST를 처음 접하는 사람도 이해하기 쉽게
REST 개념에 대해서 정리를 해보려고 한다.
REST라는 개념은 2000년에 Roy Fielding이라는 사람이 논문을 내면서 알려졌다.
네트워크 시스템의 아키텍쳐 스타일에 대해 처음 소개하면서 나온 용어이다.
Roy Fielding이란 사람은 HTTP(HyperText Transfer Protocol)의 주요 저자 중 한 사람이기도 하다.
HTTP란 www, 즉 웹 상에서 정보를 주고받을 때 쓰이는 전송 규약, 규범이다.
매우 매우 중요한 개념이고 지금 우리가 사용하는 모든 웹 사이트, 어플리케이션은 대부분 이 HTTP 규약을 따르고 있다.
그러니까 Roy Fielding은 네트워크, 통신 관련해서 엄청나게 중요한 개념들을 만든 대단한 사람이다.
Representational State Transfer
REST는 Representational State Transfer라는 단어의 약자로
인터넷 상에서 어떤 웹 어플리케이션을 구축하는데 필요한 건축적/구조적 스타일에 대한 것이다.
구조적인 "스타일" 관련이라는 것은 즉, 물리적인 것과 전혀 상관없는 디자인적인 개념이라는 것이다.
REST라는 것을 이해하기 위해서는 자원(Resources)이란 무엇인지,
Representational State Transfer라는 단어가 각각 무엇을 의미하는지에 대한 이해가 선행되어야 한다.
우리의 웹 어플리케이션은 위 그림과 같은 형태를 띄고 있다.
먼저 클라이언트와 서버가 존재한다.
서버는 데이터베이스에 직접 접근하여 리소스들을 가지고 올 수 있다.
반면 클라이언트는 데이터베이스에 직접 접근할 수 없다.
그렇기 때문에 서버에 요청을 보내 서버가 주는 응답을 통해서만 리소스에 접근할 수 있다.
만약 날씨 어플이 있다고 생각해보자.
이 날씨 어플에서 클라이언트가 서울의 오늘 날씨를 화면에 보여주기 위해
서버에 서울 날씨 리소스를 요청한다고 생각해보자.
이 때 클라이언트가 여러 도시의 날씨 정보를 가지고 있는 리소스들 중에서
서울 날씨 리소스에 접근하기 위해서는 URI(Universal Resource Identifier)
혹은 URL(Universal Resource Locator)이라는 것이 필요하다.
URI는 즉 각 리소스의 식별자, ID, 주소와 같은 것이다.
모든 리소스는 반드시 하나 이상의 URI를 가지고 있어야한다.
그래야만 여러 리소스들 중에서 원하는 리소스에 접근할 수 있기 때문이다.
위 예시의 경우에는 https://example.com/weather/seoul이
서울 날씨 리소스에 접근하기 위해 필요한 URI가 된다.
이제 서버는 클라이언트가 원하는 서울의 날씨 데이터를 클라이언트에게 보내주게 되는데
이 때 서버가 응답으로 보내는 것은 리소스 자체가 아니다.
리소스라는 것은 그냥 단순히 "오늘의 서울 날씨"라는 포괄적인 개념이다.
그러니까 리소스는 특정한 형태로 한정된 것이 아니다.
리소스는 "오늘의 서울 날씨는 22도입니다."라는 텍스트가 될 수도 있고,
오늘 날씨 정보가 그림으로 표현된 이미지 파일이 될 수도 있다.
json 형태일 수도 있고 html 형태가 될 수도 있다.
이 때 서버는 이 리소스를 클라이언트가 원하는 특정한 형태로 보내게 되는데
이것을 우리는 Representation data라고 한다.
즉 서버가 클라이언트에게 응답으로 보내는 것은 "어떤 리소스에 대한 대표"이다.
위 예시에서는 JSON 형태로 된 서울 날씨 정보가 representation data이다.
즉, Representation이란 서버가 클라이언트에게 응답으로 보내는 자원의 대표라고 정의할 수 있다.
그렇다면 State란 무엇일까?
날씨 정보는 실시간으로 바뀐다.
지금 당장은 22도이지만 5분 뒤의 날씨는 20도가 될 수도 있고 25도가 될 수도 있다.
그렇지만 응답으로 보내는 것은 특정 시점의 resource 상태를 보낸다.
즉, 내가 지금 서버에 요청해서 받은 응답은 요청된 시점의 리소스 상태를 말한다.
state란 즉 Resource의 특정 시점의 상태를 말한다.
마지막으로 Tranfer란 서버에서 클라이언트로 전송되는 것을 말한다.
결론적으로 Representational State Transfer란
"서버에서 클라이언트로 특정 시점의 자원의 대표를 전송하는 것"이다.
Content Negotiation
리소스의 representation은 그럼 누가 어떻게 결정하여 전송하는 것인가?
이는 클라이언트와 서버 간의 내용 협상(Content Negotiation)이런 것을 통해 결정된다.
이 것은 다시 Proactive negotiation(or Server-driven negotiation)과
Reactive negotiation(or Client-driven negotiation)으로 나눠진다.
Proactive 협상은 서버 주도 협상이라는 이름에서 알 수 있듯이
서버 주도하에 결정되는 것이다.
클라이언트가 보내는 특정 HTTP 헤더를 이용하는 방법인데
만약에 클라이언트가 서버에 보내는 request header에
"Accept:text/html;charset=UTF-8"이란 내용이 담겼다면
서버는 헤더를 읽은 후 클라이언트가 가장 만족해 할 형태의
리소스를 선택해서 클라이언트에게 응답한다.
즉, 결론적으로 서버가 결정하여 보내는 것이므로 서버 주도 협상이라고 한다.
반대로 클라이언트 주도 협상은 서버가 URI의 목록으로 된 선택지를 주면
클라이언트가 선택하는 형태로 서버 주도 협상이 실패했을 경우의 대비책으로 존재한다.
REST works on HTTP Protocol
REST는 HTTP 프로토콜 안에서 이루어진다.
REST는 단순히 명사들이다. 즉, 클라이언트는 서울 날씨 정보를 알기 위해서
서버에 weather/Seoul이라는 명사들을 서버에 전송했다.
그런데 서버는 명사들만으로는 어떠한 액션도 발생시킬 수 없다.
클라이언트가 원하는 것이 서울 날씨 정보를 받고 싶다는 것인지,
혹은 삭제하고 싶다는 것인지 서버는 전혀 알 수 없기 때문이다.
이 때 필요한 것이 바로 동사이다.
즉, HTTP 메소드, GET / POST / PUT / DELETE들을 말한다.
만약에 서울 날씨 명사들과 함께 HTTP GET request를 보내게 되면
서버는 클라이언트에게 날씨 정보를 가져다 줄 것이다.
만약 똑같은 요청을 DELETE 메소드와 함께 사용했다면
서버는 해당 날씨 정보를 데이터베이스에서 삭제하는 액션을 취할 것이다.
6 Architectural Constraints
REST는 아까도 설명했듯이 일종의 구조적인 스타일에 관련된 것들이다.
그래서 6가지 구조적 제약조건들을 가진다.
- Client-Server
- Stateless
- Cache
- Uniform Interface
- Layered System
- Code on Demand (Optional)
이 6가지 제약조건들에 대해서 자세히 살펴보자!
[1] Client-Server
이 제약조건은 REST 어플리케이션은 반드시 클라이언트 - 서버의 구조로 이루어져야 한다는 것이다.
이 떄 클라이언트와 서버는 반드시 분리되어있어야 하며 독립적인 존재여야 한다.
즉, 클라이언트는 리소스를 요청하는 존재이고 서버가 주는 리소스를 화면에 보여주는 역할만을 담당하며
서버는 클라이언트 UI에 대해서 전혀 관심없고 오로지 클라이언트가 원하는 정보를 찾아서 전달하는 역할만을 한다.
클라이언트와 서버가 서로 종속적이지 않기 때문에
서로에게 영향을 주지 않고 각자 버전업을 할 수 있다는 장점이 있다.
[2] Stateless
이 제약조건은 서버와 클라이언트 간의 커뮤니케이션은 반드시 stateless해야 한다는 뜻이다.
즉, 서버는 어떠한 세션 데이터도 저장해서는 안되며
모든 요청은 해당 요청을 이해하는데 필요한 모든 정보들을 포함하고 있어야 한다는 것이다.
예를 들어서 만약에 우리가 jwt토큰을 사용하여 로그인을 구현한다고 가정해보자.
서버가 토큰을 생성해서 클라이언트에게 전달할 때
서버는 이 토큰을 절대 서버 내부에 저장해서는 안된다.
클라이언트가 session storage나 cookie등에 저장해뒀다가
매번 서버에 요청을 보낼 때마다 header에 토큰을 포함해서 보내야만 한다.
이 제약조건의 장점은 visibility가 향상된다는 것이다.
visibility, 즉 눈에 잘 보인다는 것이다.
그러니까 어떤 요청을 이해하는데 필요한 모든 정보를 요청 내부에 포함하고 있기 때문에
특정 요청 하나를 가져와서 읽어보면 그 요청을 쉽게 이해할 수 있고
그 요청이 어떤 요청인지, 무엇을 위한 요청인지 쉽게 파악할 수 있다는 것이다.
반대로 단점은 매 요청 시에 정보들을 담아서 보내야하기 때문에
더 많은 네트워크 대역폭이 요구된다.
[3] Cache
이 제약조건은 가능한 한 모든 응답은 cachable해야한다는 것이다.
그리고 모든 응답은 반드시 해당 응답이 cachable할 수 있을지, 없을지에 대한 정보를 담고 있어야만 한다.
즉, 똑같은 요청을 연속적으로 보냈을때, 모든 요청을 서버에 전송하는 것이 아니라
한 번만 요청을 전송하고 응답을 어딘가에 기억해놨다가 똑같은 요청이 다시 발생했을때
캐시에 저장된 응답을 클라이언트가 가져다 쓸 수 있는 것을 말한다.
매 번 요청을 보내는 것이 아니기 때문에 네트워크 latency를 낮출 수 있다는 장점이 있다.
(latency란 어떤 요청을 보내고 응답을 받을 때까지 걸리는 시간을 의미한다.)
[4] Uniform Interface
이 제약조건은 REST API와 REST API가 아닌 것들을 구분지을 때 가장 키가 되는 제약조건이다.
이 개념은 똑같은 어플리케이션이 있다면 스마트폰에서 접속하든 노트북에서 접속하든
항상 똑같은 방식의 인터렉션이 일어나야 한다는 뜻이다.
이 Uniform Interface 제약조건을 충족시키기 위한 4가지 요소들이 있는데 다음과 같다.
- Identification of Resources (typically by an URL): https://example.com/weather/seoul이란 URL에서 weather/seoul이라는 단어만 봐도 이 URL이 seoul의 날씨 리소스와 관련된 URL이라고 알 수 있다. 즉, 단어만 보아도 어떤 리소스를 식별하는지 알 수 있어야 한다는 것이다.
- Manipulation of Resources through representations: 모든 리소스의 수정이나 변형은 반드시 representation을 이용해서 이루어져야 한다는 뜻이다.
- Self-descriptive messages for each request: 모든 요청은 본인 스스로를 잘 설명하는 메시지여야 한다는 뜻이다. 즉 아까 어떤 요청을 보낼 때는 그 요청을 이해하는데 필요한 정보를 모두 포함하고 있어야 한다는 것과 같은 맥락이다.
- HATEOS(Hypermedia As The Engine Of application State): 이것은 클라이언트가 다른 리소스를 쉽게 발견할 수 있는 링크들을 응답에 포함해서 보내야한다는 것이다.
[5] Layered System
이 제약조건은 계층적인 레이어들로 구성된 구조를 허용해야한다는 것이다.
Layered System의 가장 큰 예시로는 MVC 패턴을 들 수 있다.
MVC 패턴은 Model, View, Controller라는 각각의 레이어가 존재한다.
이 레이어들은 각자 맡은 업무만 수행하며 독립적이다.
View는 오직 화면에 보여지는 부분만 담당하며
Model은 데이터 관련된 것만 담당한다.
Controller는 그 둘 사이를 제어하는 역할이다.
이 각각의 레이어들은 인접한 레이어들 외에는 다른 레이어들이 무슨 일을 하는지 전혀 알지 못한다.
이 스타일의 장점은 보안이다.
어떤 한 레이어가 보안이 뚫리더라도 다른 레이어에 영향을 주지 않기 때문이다.
단점은 latency이다. 어떤 요청을 보내면
모든 레이어들을 지나가면서 이루어지기 때문에 속도가 지연될 수 있다.
[6] Code on Demand(Optional)
마지막 제약조건은 위의 5가지 제약조건들과는 다르게 선택사항이며
서버가 클라이언트에게 실행가능한 코드를 제공할 수 있다는 제약조건이다.
즉, 실행가능한 자바스크립트 코드와 같은 것을 서버에서 클라이언트에게 보내고
클라이언트는 받은 코드를 그대로 실행하기만 하는 형태이다.
이 스타일의 가장 큰 단점은 보안에 매우 위협이 될 수 있다는 것이다.
누군가 중간에서 코드를 해킹하면 매우 곤란해질 수 있다.
또한 visibility를 감소시킨다. 코드를 주고받기 때문이다.
이러한 단점 때문에 이 제약조건은 필수 조건이 아닌 선택 사항이다.
Conclusion
정리하자면 REST란 서버에서 클라이언트로 특정 시점의 자원의 대표를 전송하는 것이며 이는 HTTP 프로토콜 안에서 이루어진다. 6가지의 건축적/구조적인 스타일 제약 조건이 있으며 이 중 5가지 필수 사항을 지켰다면 그 웹 서비는 RESTful하다고 할 수 있다.
REST API란?
마지막으로 REST API를 간단하게 설명해보자면 이렇다.
API란 Application Programming Interface의 약자이다.
식당에서 손님이 음식을 주문할때 직접 주방으로 달려가서 주문하진 않는다.
웨이터에게 주문을 하고 웨이터가 주방에 음식을 요청하는 형태이다.
이 것을 웹 어플리케이션에 적용해보면 이 웨이터가 하는 일이 바로 API가 하는 일이다.
USER가 어떤 리소스를 원한다면 API에 요청을 하고 이 API가 USER 대신 서버에 요청을 하여
필요한 자원의 representation을 USER에게 가져다주는 역할을 한다.
▶ Reference
- https://blog.npcode.com/2017/04/03/rest%EC%9D%98-representation%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/
- https://developer.mozilla.org/ko/docs/Web/HTTP/Content_negotiation
- https://www.a-mean-blog.com/ko/blog/토막글/_/REST와-RESTful-API
- https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
- https://www.w3.org/blog/2006/02/content-negotiation/
- https://www.youtube.com/watch?v=fMXG_arerHA
- https://www.youtube.com/watch?v=HeXQ98sogs8
반응형'Computer Science' 카테고리의 다른 글
[HTTP] HTTP Method 정리 / GET vs POST 차이점 (1687) 2019.09.10 [HTTP] Cross-Origin Resource Sharing (CORS)에 대하여 (609) 2019.09.10 [자료 구조] Data Structure - (3) Tree / Binary Search Tree (609) 2019.07.14 [자료 구조] Data Structure - (2) Hash Table (968) 2019.07.11 [자료 구조] Data Structure - (1) Stack / Queue / Linked List (968) 2019.07.08 COMMENT