REST란?
- REST는 Representational State Transfer라는 용어의 약자로서 2000년도에 로이 필딩(Roy Fielding)의 박사학위 논문에서 최초로 소개 되었다.
- https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
- 로이 필딩은 HTTP의 주요 저자중 한 사람이다.
- 로이 핑딩은 당시 웹(HTTP) 설계의 우수성에 비해 제대로 사용되어지지 못하는 모습에 안타까워하며 웹의 장점을 최대한 활용할 수 있는 아키텍처로써 REST를 발표했다.
- REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다.
- REST(Representational State Transfer)는 네트워크를 통해서 컴퓨터들끼리 통신할 수 있게 해주는 아키텍처 스타일
API란?
- Application Programming Interface
- API는 정의 및 프로토콜 집합을 사용하여 두 소프트웨어 구성 요소가 서로 통신할 수 있게 하는 메커니즘이다.
- 프로그램들이 서로 상호작용하는 것을 도와주는 매개체
REST API란?
API의 역할
API는 서버와 데이터베이스에 대한 출입구 역할을 한다.
- 데이터베이스에는 소중한 정보들이 저장되는데요. 모든 사람들이 이 데이터베이스에 접근할 수 있으면 안 되겠지요. API는 이를 방지하기 위해 여러분이 가진 서버와 데이터베이스에 대한 출입구 역할을 하며, 허용된 사람들에게만 접근성을 부여해줍니다.
API는 애플리케이션과 기기가 원활하게 통신할 수 있도록 한다.
- 여기서 애플리케이션이란 우리가 흔히 알고 있는 스마트폰 어플이나 프로그램을 말합니다. API는 애플리케이션과 기기가 데이터를 원활히 주고받을 수 있도록 돕는 역할을 합니다.
3. API는 모든 접속을 표준화한다.
- API는 모든 접속을 표준화하기 때문에 기계/ 운영체제 등과 상관없이 누구나 동일한 액세스를 얻을 수 있습니다. 쉽게 말해, API는 범용 플러그처럼 작동한다고 볼 수 있습니다.
API유형
private API
- private API는 내부 API로, 회사 개발자가 자체 제품과 서비스를 개선하기 위해 내부적으로 발행합니다. 따라서 제 3자에게 노출되지 않습니다.
public API
- public API는 개방형 API로, 모두에게 공개됩니다. 누구나 제한 없이 API를 사용할 수 있는 게 특징입니다.
partner API
- partner API는 기업이 데이터 공유에 동의하는 특정인들만 사용할 수 있습니다. 비즈니스 관계에서 사용되는 편이며, 종종 파트너 회사 간에 소프트웨어를 통합하기 위해 사용됩니다.
REST 구성
- 자원(RESOURCE) - URI
- 행위(Verb) - HTTP METHOD
- 표현(Representations)
REST의 특징
Uniform(유니폼 인터페이스)
- Uniform Interface는 URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일을 뜻한다.
Stateless(무상태성)
- REST는 무상태성 성격을 가진다.
- 작업을 위한 상태정보를 따로 저장하고 관리하지 않는다.
- 세션 정보나 쿠키 정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다.
- 서비스의 자유도가 높아지도 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해진다.
Cacheable(캐시 가능)
- REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹 표준을 그대로 사용하기 때문에, 웹에서 사용하는 기존 인프라를 그대로 사용가능하다.
- 따라서 HTTP가 가진 캐싱 기능이 적용 가능하다.
- HTTP 프로토콜 표준에서 사용하는 Last-Modified 태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.
Client - Server 구조
- REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)등을 직접 관리하는 구조이다.
- 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성이 줄어들게 된다.
계층형 구조
- REST 서버는 다중 계층으로 구성될 수 있다.
- 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있다.
- PROXY, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다.
REST API의 이점
1. 통합
API는 새로운 애플리케이션을 기존 소프트웨어 시스템과 통합하는 데 사용된다. 그러면 각 기능을 처음부터 작성할 필요가 없기 때문에 개발 속도가 빨라진다. API를 사용하여 기존 코드를 활용할 수 있다.
2. 혁신
새로운 앱의 등장으로 전체 산업이 바뀔 수 있다. 기업은 신속하게 대응하고 혁신적인 서비스의 신속한 배포를 지원해야 한다. 전체 코드를 다시 작성할 필요 없이 API 수준에서 변경하여 이를 수행할 수 있다.
3. 확장
API는 기업이 다양한 플랫폼에서 고객의 요구 사항을 충족할 수 있는 고유한 기회를 제공한다. 예를 들어 지도 API를 사용하면 웹 사이트, Android, iOS 등을 통해 지도 정보를 통합할 수 있다. 어느 기업이나 무료 또는 유료 API를 사용하여 내부 데이터베이스에 유사한 액세스 권한을 부여할 수 있다.
4. 유지 관리의 용이성
API는 두 시스템 간의 게이트웨이 역할을 한다. API가 영향을 받지 않도록 각 시스템은 내부적으로 변경해야 한다. 이렇게 하면 한 시스템의 향후 코드 변경이 다른 시스템에 영향을 미치지 않는다.
REST API 설계
중요한 점
- URI는 정보의 자원을 표현해야 한다.
- 자원에 대한 행위는 HTTP Method(GET,POST,PUT,DELETE)로 표현한다.
- 버전닝(virsion)을 하지 않는다. 버전을 나누지 않는다.(논문상)
- 자원명은 복수를 사용한다 (user<x> users<o>)
리소스-> 논문에서 언급한 Representation 이라는 뜻이다.
표현은 리소스상태를 표현한다.
리소스라는 단어를 함부로 쓰면 안된다. -> 책들에서 사용을 해서 퍼졌다..
Representation을 일관성있게 사용해야 한다.
규칙
1) URI는 정보의 자원을 표현해야 한다. (리소스명은 동사보다는 명사를 사용)
GET /members/delete/1
위와 같은 방식은 REST를 제대로 적용하지 않은 URI입니다. URI는 자원을 표현하는데 중점을 두어야 합니다. delete와 같은 행위에 대한 표현이 들어가서는 안됩니다.
하지만 동사를 무조건 쓰면 안되는 것은 아니다. 하지만 사용한다면 전체적으로 통일성있고 규칙을 세우고 규칙을 지키며 사용해야한다.
영미권에서는 오퍼레이션(method)를 동사 리소스명을 명사로 해서 URI를 해석하지만 한국에서는 그렇게 해석하기가 어렵다.
2) 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE 등)로 표현
위의 잘못 된 URI를 HTTP Method를 통해 수정해 보면
DELETE /members/1
으로 수정할 수 있겠습니다.
회원정보를 가져올 때는 GET, 회원 추가 시의 행위를 표현하고자 할 때는 POST METHOD를 사용하여 표현합니다.
회원정보를 가져오는 URI
GET /members/show/1 (x)
GET /members/1 (o)
회원을 추가할 때
GET /members/insert/2 (x) - GET 메서드는 리소스 생성에 맞지 않습니다.
POST /members/2 (o)
METHOD의 역할
patch: 일부분 수정할 때 사용
URI 설계시 주의점
1) 슬래시 구분자(/)는 계층 관계를 나타내는 데 사용
http://restapi.example.com/houses/apartments
http://restapi.example.com/animals/mammals/whales
2) URI 마지막 문자로 슬래시(/)를 포함하지 않는다.
URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것이고, 역으로 리소스가 다르면 URI도 달라져야 합니다. REST API는 분명한 URI를 만들어 통신을 해야 하기 때문에 혼동을 주지 않도록 URI 경로의 마지막에는 슬래시(/)를 사용하지 않습니다.
http://restapi.example.com/houses/apartments/ (X)
http://restapi.example.com/houses/apartments (0)
3) 하이픈(-)은 URI 가독성을 높이는데 사용
URI를 쉽게 읽고 해석하기 위해, 불가피하게 긴 URI경로를 사용하게 된다면 하이픈을 사용해 가독성을 높일 수 있습니다.
4) 밑줄(_)은 URI에 사용하지 않는다.
글꼴에 따라 다르긴 하지만 밑줄은 보기 어렵거나 밑줄 때문에 문자가 가려지기도 합니다. 이런 문제를 피하기 위해 밑줄 대신 하이픈(-)을 사용하는 것이 좋습니다.(가독성)
5) URI 경로에는 소문자가 적합하다.
URI 경로에 대문자 사용은 피하도록 해야 합니다. 대소문자에 따라 다른 리소스로 인식하게 되기 때문입니다. RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문이지요.
RFC 3986 is the URI (Unified Resource Identifier) Syntax document
6) 파일 확장자는 URI에 포함시키지 않는다.
http://restapi.example.com/members/soccer/345/photo.jpg (X)
REST API에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않습니다. Accept header를 사용하도록 합시다.
GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg
리소스 간의 관계를 표현하는 방법
REST 리소스 간에는 연관 관계가 있을 수 있고, 이런 경우 다음과 같은 표현방법으로 사용합니다.
/리소스명/리소스 ID/관계가 있는 다른 리소스명
ex) GET : /users/{userid}/devices (일반적으로 소유 ‘has’의 관계를 표현할 때)
만약에 관계명이 복잡하다면 이를 서브 리소스에 명시적으로 표현하는 방법이 있습니다. 예를 들어 사용자가 ‘좋아하는’ 디바이스 목록을 표현해야 할 경우 다음과 같은 형태로 사용될 수 있습니다.
GET : /users/{userid}/likes/devices (관계명이 애매하거나 구체적 표현이 필요할 때)
자원을 표현하는 Colllection과 Document
Collection과 Document에 대해 알면 URI 설계가 한 층 더 쉬워집니다. DOCUMENT는 단순히 문서로 이해해도 되고, 한 객체라고 이해하셔도 될 것 같습니다. 컬렉션은 문서들의 집합, 객체들의 집합이라고 생각하시면 이해하시는데 좀더 편하실 것 같습니다. 컬렉션과 도큐먼트는 모두 리소스라고 표현할 수 있으며 URI에 표현됩니다. 예를 살펴보도록 하겠습니다.
http:// restapi.example.com/sports/soccer
위 URI를 보시면 sports라는 컬렉션과 soccer라는 도큐먼트로 표현되고 있다고 생각하면 됩니다. 좀 더 예를 들어보자면
http:// restapi.example.com/sports/soccer/players/13
sports, players 컬렉션과 soccer, 13(13번인 선수)를 의미하는 도큐먼트로 URI가 이루어지게 됩니다. 여기서 중요한 점은 컬렉션은 복수로 사용하고 있다는 점입니다. 좀 더 직관적인 REST API를 위해서는 컬렉션과 도큐먼트를 사용할 때 단수 복수도 지켜준다면 좀 더 이해하기 쉬운 URI를 설계할 수 있습니다.
RESTFUL이란 REST의 원리를 따르는 시스템을 의미합니다. 하지만 REST를 사용했다 하여 모두가 RESTful 한 것은 아닙니다. REST API의 설계 규칙을 올바르게 지킨 시스템을 RESTful하다 말할 수 있으며
모든 CRUD 기능을 POST로 처리 하는 API 혹은 URI 규칙을 올바르게 지키지 않은 API는 REST API의 설계 규칙을 올바르게 지키지 못한 시스템은 REST API를 사용하였지만 RESTful 하지 못한 시스템이라고 할 수 있습니다
논문 요약
현재의 REST는 처음 논문과 조금 다르게 전파가 된 부분도 있다. 논문이 쓰여진 2000년에 비해 시간이 지나 논문이 현재의 흐름과 정확히 맞지 않을 수 있다.
아래내용은 학교 계절수업(한상곤교수님) 수업자료를 그대로 가져왔습니다.
1장: Software Architecture
아키텍처 스타일(architectural style)이란, 그 스타일을 따르는 아키텍처가 지켜야 하는 제약조건들의 집합
2장: Network-based Application Architectures
이 논문에서 다루는 아키텍처 스타일의 적용 범위는 네트워크 기반 애플리케이션(Network-based Application)으로 한정된다.
네트워크 기반 소프트웨어는 operation이 네트워크를 경유해서 일어난다는 사실을 사용자에게 감출 필요가 없다. 분산(distributed) 소프트웨어는 감추어야한다.
애플리케이션이기 때문에, OS나 네트워킹 소프트웨어 같은 것은 고려 대상에서 제외된다.
네트워크 기반 애플리케이션 아키텍처의 관심 사항은 다음과 같다.
- 성능
- 규모확장성(Scalability)
- 단순성
- 수정용이성(Modifiability)
- 가시성(Visibility)
- 이식성(Portability)
- 신뢰성(Reliability)
3장: Network-based Architectural Styles
이 장에서는 Pipe and Filter, Layered-Client-Cache-Stateless-Server, Code on Demand 를 비롯한 여러가지 네트워크 기반 아키텍처 스타일들을 소개한다.
4장: Designing the Web Architecture: Problems and Insights
이 장에서는 웹 아키텍처의 요구사항, 해결해야할 문제를 설명하고 이를 해결하기 위한 접근 방법을 제시한다.
5장: Representational State Transfer (REST)
4장에서 제시한 접근방법의 결과물로 웹을 위한 아키텍처 스타일 “REST”를 소개한다. REST는 3장에서 소개했던 네트워크 기반 아키텍처 스타일들 몇 가지와 추가로 Uniform Interface 스타일을 함께 결합한 하이브리드 스타일이다.
- Client-Server – 클라이언트-서버 스타일은 사용자 인터페이스에 대한 관심(concern)을 데이터 저장에 대한 관심으로부터 분리함으로써 클라이언트의 이식성과 서버의 규모확장성을 개선한다.
- Stateless – 클라이언트와 서버의 통신에는 상태가 없어야한다. 모든 요청은 필요한 모든 정보를 담고 있어야한다. 요청 하나만 봐도 바로 뭔지 알 수 있으므로 가시성이 개선되고, task 실패시 복원이 쉬우므로 신뢰성이 개선되며, 상태를 저장할 필요가 없으므로 규모확장성이 개선된다.
- Cache – 캐시가 가능해야한다. 즉 모든 서버 응답은 캐시 가능한지 그렇지 아닌지 알 수 있어야한다. 호율, 규모확장성, 사용자 입장에서의 성능이 개선된다.
- Uniform Interface – 구성요소(클라이언트, 서버 등) 사이의 인터페이스는 균일(uniform)해야한다. 인터페이스를 일반화함으로써, 전체 시스템 아키텍처가 단순해지고, 상호작용의 가시성이 개선되며, 구현과 서비스가 분리되므로 독립적인 진화가 가능해진다. 이 스타일은 다음의 네 제약조건으로 이루어진다: identification of resources, manipulation of resources through representation, self-descriptive messages, hypermedia as the engine of application state
- Layered System – 계층(hierarchical layers)으로 구성이 가능해야하며, 각 레이어에 속한 구성요소는 인접하지 않은 레이어의 구성요소를 볼 수 없어야한다.
- Code-On-Demand (Optional) – Code-On-Demand가 가능해야한다. 서버가 네트워크를 통해 클라이언트에 프로그램을 전달하면 그 프로그램이 클라이언트에서 실행될 수 있어야한다. (Java applet이나 Javascript 같은 것을 말함) 다만 이 제약조건은 필수는 아니다.
6장: Experience and Evaluation
REST 아키텍처 스타일은 URI, HTTP 등의 웹 표준에 반영되었다.
우리가 이 논문에서 가장 주목해야 할 부분은 바로, REST를 구성하는 스타일들 중 하나인 “Uniform Interface”다. 이 스타일에 따르면, REST API는 기본 URI와 미디어 타입의 정의만 알면 이용할 수 있어야한다.
예를 들어 Github API가 REST API라면, https://api.github.com 이라는 기본 URI와 application/json의 정의만 알면 API 문서 없이도 Github API 전체가 이용이 가능해야 한다는 말이 된다. 아마 가능하지 않을 것이다. 따라서 Github API는 REST API가 아니다. 아마 세상의 거의 모든 HTTP API가 REST API가 아닐 것이다.
Code-On-Demand를 제외한 모든 스타일을 다 따라야만 REST API이기 때문에, 자신의 API를 REST API라고 부르고 싶다면 이 Uniform Interface 스타일 역시 따라야한다.
과연 Uniform Interface 스타일을 따르는 것은 가능할까? 아니 그 이전에 따르기는 해야 하는 것일까?
사실 서버가 보내준 것은 리소스가 아니다.
다음과 같은 HTTP GET 요청을 서버에 보내서
GET <https://example.org/greeting>
Host: example.org
Accept: text/plain, text/html; q=0.9 *; q=0.1
Accept-Language: en, ko; q=0.9, *; q=0.1
“hello”라는 메시지를 응답으로 받았다고 해 보자.
HTTP/1.1 200 OK
Content-Length: 6
Date: Sun, 19 Mar 2017 10:20:47 GMT
Last-Modified: Sun, 19 Mar 2017 08:00:00 GMT
Content-Type: text/plain
Content-Language: en
hello
이러한 상황을, https://example.org/greeting 라는 uri를 요청해서 “hello”라는 리소스를 응답으로 받았다고 표현하는 경우를 흔히 보았을 것이다. 그런데 그건 엄밀히 말해 약간 틀린 표현이다. 왜냐하면 “hello”는 리소스가 아니라 representation data이기 때문이다.
HTTP에서의 representation
GET 메서드의 정의는 다음과 같다.
The GET method requests transfer of a current selected representation
for the target resource.
즉, target resource에 대한 현재의 선택된 representation 하나를 반환한다.
위 정의에서 “target resource”란 https://example.org/greeting 라는 uri가 가리키는 리소스이다. 그렇다면 리소스란 무엇인가? HTTP 요청의 대상이다. HTTP는 리소스의 개념을 제한하지 않으며 무엇이든 될 수 있다. 여기서는 “hello” 라는 텍스트 자체가 리소스가 아니라, “환영의 의미를 담은 문서”가 리소스가 된다고 볼 수 있을 것이다.
그럼 “현재의 선택된 representation”이란 무엇인가? 단어 하나 하나를 차근차근 따져보도록 하자.
일단 “representation”은 무엇인가? 어떤 리소스의 특정 시점의 상태를 반영하고 있는 정보이다. 하나의 representation은 representation data와 representation metadata로 구성된다. 위의 예에서는 “hello”가 representation data이고, “Content-Type: text/plain”과 “Content-Language: en”이 representation metadata이다. (HTTP 헤더들 중 representation metadata에 해당하는 것이 있고 그렇지 않은 것이 있다.)
“현재”란 무엇인가? 이것은 말 그대로 해석하면 될 것이다. 만약 https://example.org/greeting 가 가리키는 리소스의 representation이 “hi”에서 “hello”로 수정되었다면 “현재” representation은 “hi”가 아닌 “hello”가 될 것이다.
“선택된”이라고 함은 무슨 뜻인가? 이는 하나의 리소스의 현재 representation이 하나 이상이 될 수 있으며, 그 중 하나가 선택되었음을 의미한다. 즉 “greeting” 리소스의 현재 representation은, 영어 사용자를 위한 “hello”, 한국어 사용자를 위한 “안녕하세요”, HTML 문서를 원하는 클라이언트를 위한 “<html><body>hello</body></html>”등 여러가지가 될 수 있는데, 이들 중 하나가 선택되었다는 의미이다. metadata를 포함하여 representation들의 예를 들어보자.
영어 사용자를 위한 representation:
Content-Type: text/plain
Content-Language: en
hello
한국어 사용자를 위한 representation:
Content-Type: text/plain
Content-Language: ko
안녕하세요
HTML을 선호하는 영어 사용자를 위한 representation:
Content-Type: text/html; charset=UTF-8
Content-Language: en
<html><body>hello</body></html>
HTML을 선호하는 한국어 사용자를 위한 representation:
Content-Type: text/html; charset=UTF-8
Content-Language: ko
<html><body>안녕하세요</body></html>
그렇다면 이들 중 하나를 “선택”하는 것은 누가 어떻게 하는가? 클라이언트와 서버간의 내용 협상(Content negotiation)을 통해 선택하며, 선택의 주체는 협상 방법에 따라 다르다. 사전 협상(proactive negotiation)의 경우 서버가 선택한다. 클라이언트가 GET 요청에 “Accept-Language: ko” 헤더를 포함시켜 한국어를 선호함을 밝혔다면, 서버는 가장 적절한 representation인 “안녕하세요”로 응답할 것이며, 만약 여기에 “Accept: text/html; charset=UTF-8” 헤더도 포함시켜서 한국어로 되어있고 UTF-8로 인코딩된 HTML 문서를 선호한다고 밝혔다면 “<html><body>안녕하세요</body></html>” representation을 선택하여 응답할 것이다. 만약 적절한 representation이 존재하지 않는다면 406 Not Acceptable로 응답할 것이다.
이러한 선택을 “여러 리소스 중 하나가 선택되었다”라고 말할 수 없는 이유는 무엇인가? “안녕하세요”든 “hello”든 모두 uri가 동일하기 때문이다. uri가 동일하다면 같은 리소스이다. 따라서 여러 리소스 중 하나가 선택된 것이 아니다.
주의: 서버가 uri의 목록으로 된 선택지를 주면 클라이언트가 선택하는 사후 협상(reactive negotiation)도 있는데, 이 경우는 선택지마다 uri가 각각 다를 것이므로, 클라이언트가 리소스들 중 하나를 선택한다고 표현해도 무방할지도 모른다. 자세한 것은 HTTP 명세를 참고하라.
REST에서의 representation
이처럼 HTTP 명세는 representation이라는 개념을 도입하고 있다. 그리고 이 representation은 바로 REST에서 온 것이다.
REST는 REpresentational State Transfer의 줄임말이다. “State”는 웹 애플리케이션 의 상태를 의미하며, “Transfer”는 이 상태의 전송을 의미한다.
웹 브라우저로 웹 사이트를 이용하는 예를 들어보자. 웹 페이지 A를 보고 있던 사용자가 웹 페이지 B로 가는 링크를 클릭하면, 웹 브라우저는 링크가 가리키는 웹 페이지 B를 렌더링해서 보여줄 것이다.
위의 상황에서 웹 애플리케이션은 무엇인가? 웹 브라우저와 웹 서버가 연결되어 사용자에게 가치를 제공하는 애플리케이션이다. 웹 서버가 웹 애플리케이션인 것이 아니라, 웹 브라우저가 웹 서버에 접속해야 웹 애플리케이션이다. 두 명의 사용자가 각각 자신의 웹 브라우저로 같은 웹 서버에 접속한다면, 두 개의 웹 애플리케이션이 실행되고 있는 것이다.
링크를 클릭함으로써 브라우저가 보여주던 페이지는 A에서 B로 바뀌었다. 즉, 웹 애플리케이션의 상태가 변경된 것이다. 또한 이 상태의 변경은 representation의 전송(Transfer)을 통해 이루어졌다. 그렇기 때문에 이것이 REpresentational State Transfer인 것이다.
여기서 두 가지 주의할 점이 있다.
- Transfer는 상태의 전이(transit)을 의미하는 것이 아니다. 사용자가 링크를 클릭함으로써 웹 애플리케이션의 상태가 전이된 것은 사실이지만, Transfer가 의미하는 것은 그 전이가 아니라 network component 사이에서의 전송을 말한다. 즉 이 예에서는 서버에서 클라이언트로의 웹 페이지 전송을 의미하는 것이다.
- 리소스의 상태와 애플리케이션의 상태는, 둘 다 동일하게 “state”라는 단어로 표현되고 있긴 하지만, 본질적으로 완전히 다른 것이다. 앞서 representation이란 “어떤 리소스의 특정 시점의 상태(state)를 반영하고 있는 정보”라고 말했다. 그것은 리소스의 상태지 애플리케이션의 상태는 아니다. 애플리케이션의 상태란, 웹 애플리케이션이 웹 페이지 A를 렌더링하다가 B를 렌더링하는 것으로 바뀐 그 상태를 말하는 것이다.
모든 payload는 representation
HTTP 메시지의 payload로 전달되는 모든 것은 하나의 representation이거나 적어도 그의 일부이다. PUT 메서드를 이용해 “welcome” 이란 텍스트를 전송해서, greeting 리소스의 representation을 업데이트하는 경우, 클라이언트가 서버로 전송한 “welcome”은 representation이다. 업데이트가 성공하여 서버가 “성공적으로 업데이트되었습니다”라는 메시지를 응답의 payload로 돌려보냈다면 이 메시지 역시 representation이다. “권한이 없습니다”라는 에러 메시지로 응답했다면 그 메시지도 역시 representation이다.
그렇다. 성공시나 에러시의 메시지도 역시 representation이다. 그런데 앞에서 분명 representation은 어떤 “리소스”에 대한 상태를 담은 정보라고 했다. 그렇다면 도대체 “성공적으로 업데이트되었습니다”는 어떤 리소스에 대한 것인가? greeting 리소스의 representation은 “welcome”으로 업데이트되었으니 분명 그것은 아닐 것인데 대체 무엇일까?
이론적으로 정확한 정답은 “Content-Location 헤더에 들어있는 uri가 가리키는 리소스”이다. 그러나 보통 Content-Location 헤더는 비어 있을 것이므로 현실적인 정답은 “uri를 모르는 어떤 리소스”이다. 그 메시지는 representation이 맞고, 어떤 존재하는 리소스에 대한 것이지만, 그 리소스를 가리키는 uri가 뭔지는 모른다. 이와 같은 representation을 unidentified representation이라고 하며, 어떤 payload가 unidentified representation인지 판단하는 방법은 RFC 7231의 “3.1.4.1. Identifying a Representation” 에 자세히 나와있다.
HTTP를 이용해서 오래 개발을 해 온 개발자라도 representation에 대해 잘 몰랐을 수 있다. 그것은 당연한 일이다. 왜냐하면 2014년에 HTTP/1.1이 개정되기 전 까지는 representation의 개념이 명세에 명확하게 드러나 있지 않았기 때문이다. 예를 들어 1999년부터 15년간 HTTP/1.1 명세였던 RFC 2616의 GET 메서드 정의는 다음과 같다.
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI.
이처럼 representation에 대한 명시적인 언급이 없었다.
하지만 이제 HTTP를 사용하는 개발자들은 representation에 대해 알아야 할 것이다. 그 첫 번째 이유는 오늘날의 HTTP 명세에서 수도 없이 등장하는 개념이기 때문에 이를 모른다면 명세를 올바르게 해석할 수 없기 때문이며, 두 번째 이유는 representation을 이해하지 않고서는 REST에 대해 진지하게 이야기하기가 매우 어렵기 때문이다.
참고: https://meetup.nhncloud.com/posts/92 , https://aws.amazon.com/ko/what-is/api/ , https://blog.wishket.com/api란-쉽게-설명-그린클라이언트/ , https://sigmadream.notion.site/REST-147ecbbca5e843b9b4c8498b82038a10
'I leaned > Etc' 카테고리의 다른 글
마크다운 요약정리 (0) | 2023.04.24 |
---|---|
메모리영역 (0) | 2023.04.16 |
IntelliJ 단축키(Mac) (0) | 2023.04.16 |
lombok 사용시 주의점 (0) | 2023.02.18 |
JWT - 리프레시 토큰 탈취 (0) | 2023.02.18 |