요즘 회사의 API 대부분은 REST를 기반으로 설계되고 만들어지고 있습니다. 그렇다면 REST가 무엇이고 REST API 또는 RESTful API라고 부를 수 있는 설계 원칙과 특징에 대하여 이번 게시글을 통하여 조사해봤습니다.
REST
- REST는 Representational State Transfer의 약자로, 분산 하이퍼미디어 시스템(ex. web)을 위한 소프트웨어 프로그래밍 아키텍처 스타일입니다.
- REST라는 개념은 Roy T.Fielding 박사님이 자신의 박사학위 논문에서 처음 소개하였으며, 기본적으로 HTTP 프로토콜을 더욱 잘 활용할 수 있도록 만들어진 아키텍처 스타일입니다.
REST의 일반적인 오해
REST API 에 대하여 정의를 검색해보면 많은 자료들에서 REST를 아래와 같이 정의하고 있습니다.
- HTTP URI(Uniform Resource Identifier) 를 통하여 자원(Resource)을 명시하고,
- HTTP Method(POST, PUT, GET, DELETE) 를 통하여 해당 자원에 대한 CRUD operation을 적용하는 것을 의미한다.
이번 게시글을 작성하기 위해 REST API에 관해 정말 다양한 글을 읽었습니다.
그래서 전 개발을 시작할 때부터 REST API를 배웠지만 누가 저한테 REST API에 대해 100% 아냐고 물었을 경우, 자신있게 답하지 못한다는 사실이 부끄러웠고 이번 기회를 통해 REST API에 대해 100% 알고자 노력했습니다.
그로 인해 찾은 사람은 바로 저 로이 필딩 박사님입니다.
이분에 대해 자세히 알려고 하다 보니 이분의 블로그 게시글을 추천받게 되었습니다.
https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post
이분의 게시글을 요약하자면
자신의 논문에서는 CRUD 또는 POST에 대한 언급은 없으며, REST는 오직 모든 자원(Resource)에 대하여 균일하게 정의되는 것이며 그 방법이 독자적인 정의를 따라 사용되고 있는 한 REST는 그것에 대하여 이야기하지 않는다. 라고 이야기 합니다.
이는 로이 필딩 박사님이 정의한 REST는 CRUD나 HTTP에 종속되지 않고 REST의 조건을 충족하는 경우에 REST 아키텍처 스타일이라 부를수 있으며, REST 아키텍처가 성립하는데 CRUD 의 유무는 중요하지 않다. 라는 의미로 받아들일 수 있다고 봅니다.
REST의 6가지 제약 조건
REST는 HTTP에 종속된 기술이라기보다, 분산 하이퍼미디어 시스템을 위한 아키텍처 스타일입니다. 다만 웹 API에서는 HTTP의 URI, Method, Header 등을 활용해 REST 제약조건을 적용하는 경우가 많습니다.
1. client-server (클라이언트 / 서버 구조)
- 클라이언트와 서버는 분리되어 독립적으로 역할이 명확히 구분됩니다.
- HTTP 프로토콜의 요청과 응답 구조
2. Stateless (무상태성)
- 무상태성은 첫번째로 언급한 client-server 구조의 상호작용에 대한 조건입니다.
- REST는 HTTP 프로토콜과 같이 서버가 클라이언트의 상태를 보존하지 않는 조건을 가집니다.
- 서버측에서는 클라이언트의 상태 정보를 저장하지 않습니다.
3. Cacheable (캐시 처리 가능)
- HTTP 프로토콜 헤더 필드의 Cache-Control 과 같이 캐시 처리가 가능하다는 조건입니다.
4. Layered System (계층화)
- 서버를 다중 계층으로 구성이 가능하다는 조건입니다.
- 계층형 시스템 아키텍처를 사용할 수 있으며 중계 서버를 두어 네트워크와 프로세서 사이에 로드 밸런싱을 가능하게 하여 시스템의 확장성을 확보할 수 있습니다.
5. Uniform Interface (인터페이스의 일관성)
- 클라이언트와 서버간의 상호작용을 위한 인터페이스는 일관되어야 한다는 조건입니다.
- Uniform Interface 의 제약조건이 가장 지켜지기 어려우며 이 제약 조건을 충족시키지 못하는 API 가 대부분이라고 볼 수 있습니다.
6. Code on demand (Optional)
- 서버가 클라이언트에서 실행할 수 있는 코드를 전송할 수 있다는 조건입니다.
- 해당 조건은 Optional한 조건으로 로이 필딩도 따로 다루고있지 않습니다.
Uniform Interface 제약조건
제약조건에 관해서는 솔직히 이번 기회를 통해 새롭게 알게 된 것들도 있고 전에는 잘 몰랐던 것들입니다.
그런데 이 제약조건 6가지 중 제일 강조되는 바로 Uniform Interface 이므로 좀 더 자세히 알아보도록 하겠습니다.
1. 자원의 식별 (Identification of Resources)
- URI (Uniform Resource Identifier) 를 통하여 자원(Resource)를 식별해야 합니다.
2. 표현을 통한 자원의 조작 (manipulation of resources through representation)
- 표현을 통하여 자원의 상태를 조작해야합니다.
- 표현은 자원의 상태를 담은 JSON, XML, HTML 등의 데이터 형태를 의미하며, HTTP Method는 해당 표현을 조회하거나 변경하기 위한 동작을 나타냅니다.
3. 자기 서술적 메시지 (self-descriptive messages)
- 자원의 요청이나 응답에는 자신에 대한 모든 정보가 포함되어야 합니다.
Example
Request
GET /users
위 요청이 self-descriptive 를 충족하기 위해서는 목적지 에 대한 정보가 필요합니다. 그러므로 아래와 같이 목적지가 추가 되었을 경우, self-descriptive 를 충족했다고 판단할 수 있습니다.
GET /users
Host: www.example.org
Response
HTTP/1.1 200 OK
Content-Type: application/json
[{ "op": "add", "path": "/hello", "value": ["world"] }]
위 응답 형태는 일반적으로 json 데이터로 응답 받는 경우의 응답 구조이지만 self-descriptive 를 충족했다고 보기에는 어렵습니다.
json으로 데이터가 응답된다라는 정보가 헤더에 들어있으나 내부 데이터가 무엇으로 정의되어 있는지에 대한 설명이 없기때문입니다.
self-descriptive를 충족하기 위해서는 아래와 같이 응답 데이터가 어떻게 정의되어 있는지 상세하게 상태를 전달해야 합니다.
HTTP/1.1 200 OK
Content-Type: application/json-patch+json
[{ "op": "add", "path": "/hello", "value": ["world"] }]
위와 같이 json-patch 명세로 데이터를 해석할 수 있음을 상세히 정의해주어야 비로소 self-descriptive를 충족 했다고 할수 있습니다.
4. 애플리케이션 상태의 엔진으로써 하이퍼미디어 (hypermedia as the engine of application state)
- self-descriptive message 와 같이 가장 지켜지기 어려운 제약 조건입니다.
- Hypermedia (link) 를 통하여 자기 자신에 대한 정보가 전달되어야 하며 이를 통하여 상태 전이가 가능해야 한다는 제약 조건입니다.
RESTful

추가적으로 RESTful에 대해 알아봤습니다. 간단하게 설명하자면
RESTful이란 REST의 원리를 따르는 시스템을 의미합니다. 하지만 REST를 사용했다 하여 모두가 RESTful 한 것은 아닙니다. REST API의 설계 규칙을 올바르게 지킨 시스템을 RESTful하다 말할 수 있으며
모든 CRUD 기능을 POST로 처리 하는 API 혹은 URI 규칙을 올바르게 지키지 않은 API는 REST API의 설계 규칙을 올바르게 지키지 못한 시스템은 REST API를 사용하였지만 RESTful 하지 못한 시스템이라고 할 수 있습니다.
저만의 정리
- REST는 API가 아니라 API를 디자인 하기 위한 패턴이다.
- REST는 API설계를 위한 스타일이지 HTTP에 종속된 건 아니다. HTTP에서 적용하기 쉬운 이유는 REST의 원칙들 중 다수가 HTTP로부터 영향을 많이 받았기 때문이다.
- 하지만 웹에서의 주요 프로토콜이 HTTP이기 때문에 웹개발자 입장에선 대부분의 REST API 설계를 HTTP 위에서 하게 되는 것이다. 하지만 이도 REST가 HTTP에 종속되었다는 것은 아니다!
- 꼭 REST의 규칙들을 모두 지키는 REST API를 만드는 것이 모든 상황에서 좋냐는 물음에는 아니라고 말할 수 있을 것 같다. 이 모든 것을 지켜서 만드는 것이 모든 상황에서 효율적이라 할 수 없고 로이 필딩도 “시스템 전체를 통제할 수 있다고 생각한다면 REST를 따지느라 시간을 낭비하지 말라”라고 말하고 있다.
마무리
이번 글을 작성하며 REST를 단순한 CRUD API 규칙이 아니라 아키텍처 스타일 관점에서 이해할 수 있었습니다.
다음 포스팅은 REST의 확장 버전인 Swagger와 Spring REST Docs에 대해 조사하겠습니다.
위 포스팅이 참고한 기술 블로그는
- https://helloworld.kurly.com/blog/spring-rest-docs-guide/
- https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post