소개

REST는 Representational State Transfer의 약자로, 네트워크 어플리케이션을 디자인하기 위한 아키텍쳐 스타일이다. 이것은 장비 간 통신을 위해 CORBA, RPC, 혹은 SOAP등의 복잡한 방법을 사용하는 대신, 간단하게 HTTP를 이용하는 것을 목적으로 한다.
REST는 자원 지향 구조(Resource Oriented Architecture)로 웹 사이트의 이미지, 텍스트, DB 내용 등의 모든 자원에 고유한 URI를 부여한다. 한 가지 알아두어야 할 것은, REST가 표준은 아니라는 것이다. 월드 와이드 웹의 표준을 개발하고 장려하는 W3C는 REST를 사용하라고 하지는 않는다.

CRUD

REST에서 자원에 대한 작업은 HTTP Request를 이용한다. 작업에는 Create(생성), Read(조회), Update(수정), Delete(삭제)가 있고, 이를 줄여서 CRUD라고 한다. 여기에 대응하는 HTTP 메소드는 각각 Post, Get, Put, Delete이다. 실제로 HTTP Reqeust를 보내고 결과를 받는 부분을 살펴보자.

Request

1
2
GET /
Accept: application/userdb

Response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
200 OK
Content-Type: application/userdb

{
"version": "1.0",
"links": [
{
"href": "/user",
"rel": "list",
"method": "GET"
},
{
"href": "/user",
"rel": "create",
"method": "POST"
}
]
}

조건

REST 아키텍쳐는 다음과 같은 6개의 조건을 가진다.

1. Uniform Interface

REST는 HTTP 표준에만 따른다면, 특정 언어나 기술에 구애받지 않고 사용이 가능한 인터페이스 스타일이다. HTTP의 창시자 중 한 사람인 Roy Fielding은 네 가지의 인터페이스 제약을 제시했다.

  • Resource-Based 의역하자면 리소스 식별 로, 각각의 리소스는 URI를 구분자로 이용하여 구분되어야 한다는 것이다. 예를 들어, http://www.google.com 은 구글의 메인 페이지를 정의한다.
  • Manipulation of Resources Through Representations 표현을 통한 리소스 처리 는 같은 리소스라도 클라이언트에 따라 다르게 보여질 수 있다는 것이다. 뉴스 사이트를 생각해보자. 데스크탑으로 접속할 때와 모바일로 접속할 때 화면은 서로 다르지만 같은 리소스를 쓰고 있다.
  • Self-descriptive Messages 자기 서술적 메시지 란 각 메시지는 자신을 어떻게 처리해야 하는지에 대한 모든 정보를 포함해야 한다는 것이다. 이러한 종류의 메시지는 state-less 혹은 context-free 라고 부르기도 한다.
  • Hypermedia as the Engine of Application State (HATEOAS) 메시지를 보내는 것은 어플리케이션의 상태를 변화시킨다. 예를 들어, 새로운 유저 정보를 서버에 POST하게 되면 유저 리스트를 하나 늘려 어플리케이션의 상태를 변화시킨다. GET을 통해 유저 목록을 요청하면 어플리케이션의 새로운 상태를 받을 수 있다. POST와 GET은 모두 hypermedia link 를 통해 수행되는데(<a href=~>, <form action=~>), 이런 방법을 통해 RESTful 어플리케이션은 하이퍼미디어를 통해 어플리케이션의 상태를 변화시킨다. 이를 어플리케이션 상태 엔진으로서의 하이퍼미디어 라고 한다.

2. Stateless

상태가 없다는 것은 각각의 요청 시에 클라이언트의 컨텍스트가 서버에 저장되지 않는다는 것이다. 클라이언트가 보내는 각각의 요청은 필요한 모든 정보를 담고 있어야 한다. 이렇게 개발하게 되면 서버는 들어오는 요청만을 처리하면 되기 때문에 구현이 단순해진다.

3. Cacheable

WWW에서와 같이, 클라이언트는 응답을 캐싱할 수 있다. 대부분의 서비스에서 CURD중 Read가 가장 빈번하게 호출되기 때문에, 응답을 캐싱하는 것은 서비스의 성능을 향상시킬 수 있다. 클라이언트가 Last-Modified 값을 보냈을 때, 컨텐츠에 변화가 없다면 서버는 304 Not Modified 를 리턴하게 되고 클라이언트에서는 캐시에 저장된 값을 이용하게 된다.

1
2
3
4
5
6
7
8
9
10
GET /partners/UK

200 OK
Last-Modified: Sun, 21 Jan 2007 09:35:19 GMT
[response]

GET /partners/UK
If-Modified-Since: Sun, 21 Jan 2007 09:35:19 GMT

304 Not Modified

4. Client-Server

Uniform Interface는 서버로부터 클라이언트를 분리한다. 클라이언트는 데이터베이스를 신경 쓸 필요가 없고, 사용자 인증이나 컨텍스트를 관리한다. 서버의 경우 유저 인터페이스나 유저 상태를 신경 쓸 필요 없이 API 제공, 데이터 저장, 그리고 로직 처리의 역할만을 담당하게 되어 더 간단해지고 확장이 쉬워진다. 이렇게 역할 구분이 확실해지면 서로의 개발에 있어 의존성이 줄어들게 된다.

5. Layered System

클라이언트는 API 서버만 호출할 뿐, 자신이 대상 서버에 직접 연결되었는지 혹은 중간 서버를 통해 연결되었는지 알 수 없다. 하지만 서버는 다중 계층으로 구성될 수 있다. 서버는 API 서버에 로드밸런싱, 공유 캐시, 암호화 등을 수행하는 계층을 추가해서 유연한 구조로 개발될 수 있다.

6. Code on Demand (optional)

서버는 Java Applet이나 JavaScript와 같이 클라이언트가 실행할 수 있는 코드을 전송하여 클라이언트의 기능을 확장시킬 수 있다. 이것은 REST 아키텍쳐에서 필수는 아니다.

참고

Wikipedia
REST API Tutorial
remotti blog
SLiPP 스터디
조대협의 블로그
일관성 있는 웹 서비스 인터페이스 설계를 위한 REST API 디자인 규칙