회사에서 REST에 대한 강의를 들을 기회가 있어, 강의를 듣고 정리해보았다.
ToC
- REST란?
- Why REST?
- RESTful API?
- REST API 특징
- Rest API 디자인 가이드
- Five clues that your api isn’t RESTful.
- REST 약점
REST
REST를 한 문장으로 정의하면, REST는 HTTP 프로토콜을 사용하는 아키텍처이다.
REST란 일반적으로 HTTP method와 URI까지를 이야기한다.
Why REST?
How do I imporve HTTP without breaking the Web
HTTP의 주요 저자중 한 사람인 Roy Fielding이 HTTP 설계의 우수성에 비해 제대로 사용되어지지 못하는 모습에 안타까워하여 HTTP의 장점을 최대한 활용하는 아키텍처 로써 박사학위 논문에서 소개한 아키텍처이다.
한 문장으로 정리한다면, API 역할에 따라 HTTP 스펙을 더 잘 사용하기 위한 아키텍쳐가 REST 라고 할 수 있다.
REST 특징
- Uniform Interface
- 자원의 위치가 아닌 HTTP 메서드로 접근하는 대상이 무엇인지를 구체적이고, 명확히 표현한다.
- 무상태성 (Stateless)
- 세션, 쿠키없이 HTTP로만 독립적으로 통신이 가능해야한다.
- 캐시가능 (Cacheable)
- REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹 표준을 그대로 사용하기 때문에 웹에서 사용하는 기존 인프라를 그대로 활용이 가능하다는 점이다. 따라서 HTTP가 가진 캐싱을 적용가능하다.
- 자체 표현구조 (Self-descriptiveness)
- REST의 또 다른 큰 특징 중 하나는 REST API 메세지만 보고도 이를 쉽게 이해할 수 있는 표현이어야 한다.
- Client - Server 구조
- REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보) 등을 직접 관리하는 구조로 각각의 역할이 명확하게 구분되어야 한다.
- 계층형 구조 (Hierarchical Structure)
- REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있으며 Proxy, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게한다.
REST API 디자인 가이드
REST API 설계시 신경써야할 두가지 설계 가이드이다.
- URI는 리소스를 표현해야 한다.
- 리소스에 대한 행위는 HTTP method로 표현한다.
REST의 뜻인 Representational State Transfer에서 알 수 있듯이 REST는 어떻게 표현되는가가 중요한 아키텍처이다.
REST는 HTTP method만 사용한다고 REST라고 할 수 없다. URI 설계를 잘해야 RESTful API라고 할 수 있다. URI만으로 이 API 메세지의 의도를 개발자가 직관적으로 이해할 수 있을 때, RESTful API라고 할 수 있다.
1 | HTTP-method {service-name}/{api-version}/{resource-category}/{resource-path}/{path-variable} |
1 | GET tmap/2.1/location |
URI 설계를 직관적으로 하기 위해서는 HTTP 메서드를 용도에 맞게 사용할 수 있어야 한다. 아래의 테이블은 간단한 CRUD를 구현하는 HTTP 메서드이다.
methods | description |
---|---|
GET | 리소스를 조회한다. 리소스를 조회하고 해당 도큐먼트에 대한 자세한 정보를 가져온다. |
POST | 해당 URI를 요청하면 리소스를 생성한다. |
PUT | 리소스가 없으면 리소스를 생성하고, 리소스가 있으면 리소스를 업데이트한다. |
PATCH | 리소스를 수정한다. |
DELETE | 리소스를 삭제한다. |
리소스를 업데이트 해주는 HTTP 메소드는 PUT도 되고, PATCH도 될 수 있다. 언듯 비슷해보이는데, 각각의 메소드는 언제 사용해야 하는걸까?
스택오버플로우에도 위와 같은 질문이 올라왔는데, 아래 링크를 첨부한 자바 가이드에서와 마찬가지로 각각의 메소드를 이해하면 언제 사용할지를 알 수 있다.
PUT 메소드는 리소스가 없으면 생성하고, 있으면 업데이트한다고 위에서 테이블에 정리했지만, 더 정확히 표현하면 리소스를 교체하는 수준으로 리소스 전체(entirely)를 바꾼다.
반면 PATCH 메소드는 리소스의 일부만 변경하고자 할 때, 사용하는 HTTP 메소드이다.
예를 들어 이메일, 이름, 비밀번호라는 3개의 속성을 갖는 회원정보중 이메일만 변경하고자 할 때는 PUT이 아니라 PATCH를 사용하는게 보다 더 RESTful 하다고 할 수 있다.
URI 작성규칙
RESTful API를 위한 URI 작성 규칙은 다음과 같다.
- 명사(noun)
- HTTP methods가 동사(verb)이므로 URI마저 동사로 작성한다면, API 의미가 직관적이지 이지 않게된다.
GET /fruits/bananas
- 요청한다. 과일들 중 바나나를.
- 복수형(mutiple)
- API는 특성상 리소스들이 하나기보다는 복수형일 수 있다. 위의 API를 해석하면, 과일 중 바나나를 요청한다고 했을때, 바나나가 1개만 조회될리 없기 때문이다.
- 구체적(specifically)
- URI 만으로 해당 API가 RESTful한지 아닌지를 판단할 수 있기 때문에 URI는 추상적이지 않고 구체적일수록 좋다.
- 과일을 요청하는게 아니라 바나나를 요청해야한다.
RESTful API?
RESTful하다는 표현과 REST를 아키텍쳐라고 표현한 부분에서 알 수 있듯이 REST는 규약(protocol)이 아니다. 따라서 REST는 이분법적으로 판단할 수 없으며, 추상적으로 판단할 수 밖에 없다. REST의 조건을 충분히 충족시키는 API를 RESTful 하다는 다소 추상적인 표현을 하는 이유이다.
Five clues that your api isn’t RESTful.

- It has a single endpoint.
GET /phones
- 이런 API는 RESTful 하지 않는 API이다. 아래의 API가 더 직관적이며, RESTful API라고 할 수 있는 API이다.
GET /devices/phones
- All requests are POSTs.
- 무조건 POST method로만 API를 작성하는 것도 RESTful하지 않은 방식이다. API의 기능에 따라 HTTP method를 다양하게 활용할 수 있어야 한다.
- Response meta data is in the body.
- 메타 데이터는 최대한 HTTP header에 포함해야한다.
- status는 body로 보낼 필요가 없는 데이터이다.
- response 메타데이터(결과 값, 세션 키)는 body가 아니라 header에 포함되어야 한다.
- 요청 경로에 리소스가 없을때 : 404
- 요청 정보가 정확하지 않을때 : 400
- 인증에 실패했을때 : 401
- 요청에 성공했을때 : 200
- body에는 결과 값이나 인증 키같은 메타데이터가 아니라 순수 데이터만 포함시켜야 한다.
- There are verbs in the URL.
- HTTP method가 이미 동사(verb)기 때문에 URI이 명사(noun)로 작성되어야 API가 더 직관적으로 표현된다.
- The URL includes method names.
- REST는 resource를 표현하는 아키텍처라고 설명했다. 따라서 URL에 메서드명을 노출하는건 RESTful하지 않은 방식이다.
- 더군다나 url 작성 규칙과 프로그래밍 언어단에서의 메서드 작성 규칙은 다르기 때문에 메서드명이 url에 등록이 되면 안된다.
REST 약점
- HTTP 메서드를 사용하기 때문에 모바일/웹 등 사용할 수 있다는 인프라 범위가 넓다는 장점이 있지만, HTTP 메서드를 사용하기 때문에 제한적이라는 단점 또한 존재한다.
- 표준이 존재하지 않기때문에 REST API 디자인 가이드가 따로 존재하지 않는다. 그래서 Lorna Mitchell이 작성한 글(Five clues that your api isn’t festful)처럼 RESTful API를 위한 약속들만 존재한다.