REST API
REST이란?
REST는 Representational State Transfer라는 용어의 약자로서 월드 와이드 웹(WWW)과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다. 2000년도에 로이 필딩 (Roy Fielding)의 박사학위 논문에서 최초로 소개되었다. 로이 필딩은 HTTP의 주요 저자 중 한 사람으로 그 당시 웹(HTTP) 설계의 우수성에 비해 제대로 사용되어지지 못하는 모습에 안타까워하며 웹의 장점을 최대한 활용할 수 있는 아키텍처로써 REST를 발표하였다.
필딩의 REST 원리를 따르는 시스템은 종종 RESTful이란 용어로 지칭된다. 열정적인 REST 옹호자들은 스스로를 RESTafrians 이라고 부른다.
REST 의 특징
-
Uniform Interface (유니폼 인터페이스)
Uniform Interface는 URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일을 말한다. 쉽게 말하자면 시스템 REST API를 정의했다면, 안드로이드나 iOS 플랫폼 상관 없이, 또는 C/C++, Java, Python 등의 특정 언어나 기술에 종속 받지 않고 HTTP를 사용할 수 있는 모든 플랫폼에 사용이 가능한 느슨한 결함(Loosely coupling) 형태의 구조이다. -
Stateless (무상태성)
REST는 무상태성 성격을 갖는다. 다시 말해 작업을 위한 상태정보를 따로 저장하고 관리하지 않는다. 세션 정보나 쿠키정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다. 때문에 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해진다. -
Cacheable (캐시 가능)
REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹표준을 그대로 사용하기 때문에, 웹에서 사용하는 기존 인프라를 그대로 활용이 가능하다. 따라서 HTTP가 가진 캐싱 기능이 적용 가능하다. HTTP 프로토콜 표준에서 사용하는 Last-Modified태그나 E-Tag를 이용하면 캐싱 구현이 가능하다. -
Client - Server 구조
REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성이 줄어들게 된다. -
Self-descriptiveness (자체 표현 구조)
REST의 또 다른 큰 특징 중 하나는 REST API 메시지만 보고도 이를 쉽게 이해 할 수 있는 자체 표현 구조로 되어 있다는 것이다. -
Layered System(계층형 구조)
REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다. -
Code on demand (optional)
자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다.
REST 구성 요소
Resource (자원)
REST에서 가장 중요한 개념은 바로 유일한 ID를 가지는 Resource가 서버에 존재하고, 클라이언트는 각 Resource의 상태를 조작 및 조회를 하기 위해 요청을 보낸다. 일반적으로 Resource의 예로는 user, group 등과 같은 명사형의 단어이고, HTTP에서 이러한 Resource 를 구별하기 위한 ID는 ‘groups/{groupId}/users/{userId}‘와 같은 URI을 뜻한다.
Method (행위)
Resource를 조작할 수 있는 동사형의 단어를 Method라고 한다. 클라이언트는 URI를 이용해서 Resource를 지정하고 해당 Resource를 조작 및 조회를 하기 위해서 Method를 사용한다. HTTP에서는 GET, POST, PUT, DELETE 등의 Method를 제공한다.
Representation of Resource (표현되는 자원)
클라이언트가 서버로 요청을 보냈을 때, 서버가 응답으로 보내주는 Resource의 형태를 Representation이라고 한다. REST에서 하나의 Resource는 여러 형태의 Representation으로 나타내어 질 수 있다. 예를 들어 xml, json, text, rss 등으로 전달된다.
HTTP Methods
HTTP 에는 여러가지 Method가 있지만 REST에서는 CRUD(Create Read Update Delete)에 해당 하는 4가지의 메서드만 사용한다.
HTTP Verb | CRUD | Entire Collection (e.g. /customers) | Specific Item (e.g. /customers/{id}) |
---|---|---|---|
POST | Create | 201 (Created), ‘Location’ header with link to /customers/{id} containing new ID. | 404 (Not Found), 409 (Conflict) if resource already exists.. |
GET | Read | 200 (OK), list of customers. Use pagination, sorting and filtering to navigate big lists. | 200 (OK), single customer. 404 (Not Found), if ID not found or invalid |
PUT | Update/Replace | 405 (Method Not Allowed), unless you want to update/replace every resource in the entire collection. | 200 (OK) or 204 (No Content). 404 (Not Found), if ID not found or invalid. |
DELETE | Delete | 405 (Method Not Allowed), unless you want to delete the whole collection—not often desirable. | 200 (OK). 404 (Not Found), if ID not found or invalid. |
Resource Naming (자원 명명 규칙)
자원에 대한 명명 규칙은 HTTP Method(GET, POST, PUT, DELETE 등)를 적절하게 활용하는 것 외에도 이해하기 쉽게 활용되는 웹 서비스 API를 만들 때 가장 많이 논의되기도 하고 중요한 개념이다. 자원의 이름이 정해진 API는 직관적이며 사용하기 쉽다.
REST에서 중요한 항목 2가지가 있다.
- URI는 정보의 자원을 표현해야 한다.
- 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE 등)으로 표현한다.
URI는 리소스만 표현하고, 자원에 대한 행위는 HTTP Methods을 표현한다.
리소스명은 동사보다는 명사를 사용하고, 행위(create, update delete 등)의 행위 포함하지 않는다.
- GET : users/update/1 (X)
- PUT : users/1 (O)
첫번째 경우는 REST를 제대로 적용하지 않은 URI이다. URI는 자원을 표현하는데 중점을 두어야 한다. update와 같은 행위에 대한 표현이 들어가서는 안된다. 사용자 정보 편집을 위한 API라면 PUT을 사용한다.
URI에 리소스명은 복수로 표현한다.
계층 구조의 URI 노드는 복수 명사를 사용한다.
- GET /user/329 (X)
- GET /users/329 (O)
위에 두개는 논란이 있긴 하지만 일반적으로 인정되는 관례는 노드 이름에 항상 복수형을 사용하여 모든 HTTP 메소드에서 API URI를 일관성있게 유지하는 것이다. 이 추론은 사용자 목록 이고 ID(예:329)가 목록중에 있는 사용자 하나를 참조하는 개념을 기반으로 한다.
URI에 파일 확장자는 포함시키지 않는다.
- GET : /users/345/profile.jpg (X)
- GET : /users/345/profile - HTTP/1.1 Host: restapi.example.com Accept: image/jpg (O)
REST API에서는 Request Body 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다. Accept header를 사용한다.
URI에 슬래시(/) 구분자
슬래시 구분자(/) 계층 관계를 나타내는 데 사용하고 URI 마지막 문자로 슬래시(/)를 포함하지 않는다.
- /users/{userid}/books/ (X)
- /users/{userid}/books (0)
리소스 간의 관계를 표현하는 방법
REST 리소스간에는 서로 연관관계가 있을 수 있다. 예를 들면 사용자의 친구들 목록을 표현하는 경우, 사용자가 소유하고 있는 책의 목록 들을 표현이 필요한 경우가 있다.
- 서브 리소스로 표현하는 방법 (일반적으로 소유 ‘has’의 관계를 표현할 경우)
- /users/{userid}/friends : 사용자의 친구 목록을 표현
- /users/{userid}/books : 사용자가 소유하고 있는 책의 목록을 표현
- 서브 리소스에 관계를 명시 하는 방법 (관계명이 애매하거나 구체적 표현이 필요할 경우)
- /users/{userid}/recommand/books : 사용자 추천하는 책 목록
위에 1, 2은 어느것을 사용해도 좋으나 관계를 확실히 할 경우에는 2번을 사용해도 된다.
URI은 소문자가 적합하다.
URI 경로에 대문자 사용은 피하도록 한다. 대소문자에 따라 다른 리소스로 인식하게 되기 때문이다. RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정한다.
- /Users/{userid}/Books (X)
- /users/{userid}/books (O)
HTTP Status Codes(응답 상태 코드)
잘 설계된 REST API는 URI뿐만 아니라 그 리소스에 대한 응답을 잘 내어주는 것까지 포함되어야 한다. 정확한 응답의 상태코드만으로도 많은 정보를 전달할 수가 있기 때문에 응답의 상태코드 값을 중요하다. 혹시 성공 200이나 500 관련 특정 코드 정도만 사용하고 있다면 처리 상태에 대한 좀 더 명확한 상태코드 값을 사용하도록 한다. REST에서 꼭 필요한 상태코드에 아래와 같다.
2xx Success
코드 | 설명 |
---|---|
200 OK | 서버가 요청을 제대로 처리했다는 뜻이다. 이는 주로 서버가 요청한 페이지를 제공했다는 의미로 쓰인다. |
201 Created | 성공적으로 요청되었으며 서버가 새 리소스를 작성했다. |
204 No Content | 서버가 요청을 성공적으로 처리했지만 콘텐츠를 제공하지 않는다. |
3xx Redirection
코드 | 설명 |
---|---|
304 Not Modified | 마지막 요청 이후 요청한 페이지는 수정되지 않았다. 서버가 이 응답을 표시하면 페이지의 콘텐츠를 표시하지 않는다. 요청자가 마지막으로 페이지를 요청한 후 페이지가 변경되지 않으면 이 응답(If-Modified-Since HTTP 헤더라고 함)을 표시하도록 서버를 구성해야 한다. |
4xx Client Error
코드 | 설명 |
---|---|
400 Bad Request | 서버가 요청의 구문을 인식하지 못했다. |
401 Unauthorized | 이 요청은 인증이 필요하다. 서버는 로그인이 필요한 페이지에 대해 이 요청을 제공할 수 있다. 상태 코드 이름이 권한 없음(Unauthorized)으로 되어 있지만 실제 뜻은 인증 안됨(Unauthenticated)에 더 가깝다. |
403 Forbidden | 서버가 요청을 거부하고 있다. 예를 들자면, 사용자가 리소스에 대한 필요 권한을 갖고 있지 않다. (401은 인증 실패, 403은 인가 실패라고 볼 수 있음) |
404 Not Found | 서버가 요청한 페이지를 찾을 수 없다. 예를 들어 서버에 존재하지 않는 페이지에 대한 요청이 있을 경우 서버는 이 코드를 제공한다. |
5xx Server Error
코드 | 설명 |
---|---|
500 Internal Server Error | 서버에 오류가 발생하여 요청을 수행할 수 없다. |