다양한 web service에서 제공하는 RESTful api들에 왜 RESTful이 붙는지, 그리고 그것이 어떤 것을 의미하는 것인지를 공부하고 정리하기 위해 이 포스트를 작성합니다.

개요

RESTful을 단지 서버에서 DB에 있는 내용을 client에 제공하기 위한 일종의 develop api를 정의하는 방식이라고 생각하고 공부를 시작하였다. 이 단어를 flickr를 이용하는 application을 만들면서 처음 접했기 때문에 단편적인 면만 봐서 그런 오해를 했었던 것 같다.
REST는 내가 지금까지 본 바로는 일종의 URI와 URI 표현을 정의하는 가이드이다. 또한 URI를 통해 resource를 어떻게 표현할 지에 대해서도 포함하는 개념이다. 물론 이 개요는 이 포스트가 끝날 때쯤에는 바뀌거나 추가될 예정이다.

flicker api는 Flicker api service에서 확인할 수 있지만 권장하지 않는 스타일이기 때문에 그냥 참고만 하길 바란다.

REST?

RESTRepresentational State Transfer의 약자로, 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식입니다. Roy Fielding에 의해 처음 쓰인 용어(필딩 논문)로써 일반적인 웹(혹은 유사한)을 만들기 위한 제약 조건들을 나열한 제안하는 일종의 디자인 가이드입니다. HTTP 1.0이후 웹의 성공으로 인해 HTTP 프로토콜의 의도에 맞지 않은 사용들도 늘어나 확장성이나 유지보수성이 좋지 않은 웹이 늘어나면서 다시한번 주목을 받게 되었습니다.

그래서 뚜렷한 정의가 있기 보다는 몇가지 제약 및 제한 사항을 REST라고 부릅니다. 해당 논문이 1990년대에 발표되었기 때문에 그 당시의 원칙에서 현재 권장하는 스타일이 추가되었기 때문에 다양한 Best practice들도 통틀어서 부르기도 합니다.

아래 설명할 6가지 조건을 REST라고 하며 이를 잘 지키는 서비스 디자인을 보고 RESTful하다고 합니다.

  • Uniform Interface
  • Client-Server
  • Stateless
  • Cacheable
  • Layered System
  • Code on Demand(optional)

Uniform Interface

웹에 바람직한 구조적 특성을 부여하는 규칙이며, 리소스 식별, 표현을 통한 리소스 조작, 자기 서술 메시지, 에플리케이션 상태의 엔진으로서의 하이퍼 미디어로 구성되어 있다. 위에서 말했듯 REST는 이 아래의 원칙을 의미한다.

아래는 URI와 관련된 원칙이라고 보면 일단은 이해가 될 것이다.

리소스 식별

각각의 리소스는 URI를 구분자로 식별이 가능해야 한다. 예를들어, http://www.google.com은 구글의 메인 페이지를 나타낸다.

TO-DO list 웹사이트를 예로 들자면 아래와 같을 것이다.

http://www.example.com/v2/tasks # 할 일들의 collection
http://www.example.com/v2/tasks/2 # id 값이 2인 할 일
http://www.example.com/v2/tasks/14 # id 값이 14인 할 일

표현을 통한 리소스 처리

리소스 자체를 전송하는 것이 아닌 리소스의 표현을 전송한다.
예를 들어, GET http://www.example.com/v2/apple 는 사과 그 자체(리소스)가 아닌 사과를 묘사한 표현를 전송한다. 리소스 자체가 아닌 표현을 사용함으로써 서버의 코드에 얽메이지 않고 client를 구현할 수 있고, 서버의 수정에 거의 영향을 받지 않는다.(최소한 영향을 줄일 수 있다.)

예를 들어 Database에 있는 리소스를 요청할 경우에 Database에 있는 그대로 응답을 할 경우에는 추후 database scheme가 변경될 경우에 클라이언트가 영향을 받을 수 있어 수정에 제약이 걸릴 수도 있다.

자기 서술형 메시지

REST는 메시지가 자신을 어떻게 처리해야 할 지에 대한 정보를 포함하고 있어야 한다. 즉 수신자가 이해하기 위한 모든 정보를 가지고 있어야 한다.

아래 내용을 로이 필딩의 논문에서 제시된 몇가지 예시다:

  • state-less 시스템에서 서버는 클라이언트의 요청을 처리했던 이력을 저장하지 않는다. 그렇기 때문에 각각의 요청에 해당 정보가 포함되어야 한다.
  • 표준 method(GET, POST, DELETE, PUT)와 미디어 유형을 사용하여 별도의 설명 없이 명확하게 파악할 수 있도록 한다.

    PUT method를 사용할 경우 수정한다는 의미를 파악할 수 있고 Content-Type에 json이 명시되어 있을 경우 client는 response 메시지를 읽기 위한 방법을 알 수 있다.

  • Response에 캐시 가능성을 지정한다. Client가 아닌 server가 해당 내용을 header에 명시해야 한다.

하이퍼미디어 제약

애플리케이션의 상태는 하이퍼미디어에 의해 변경된다는 의미이다.

<!-- GET로 task들의 list를 가져오고 -->
<a href="http://example.com/v2/tasks"/>
<!-- POST로 task를 추가한다 -->
<form action="http://example.com/v2/tasks"/>

위에서처럼 클라이언트의 하이퍼 미디어에 의해 어플리케이션에 task가 추가되고 제거(상태 변화) 된다는 제약이다.

정확하게 이해했는지는 모르겠지만 애플리케이션의 상태를 변경하는 것은 클라이언트의 책임이고, 클라이언트는 하이퍼 미디어 컨트롤을 통해 상태를 변경하기 때문에 이러한 원칙이 있는 듯 하다.


Client-Server

서비스가 수행되길 기대하는 클라이언트 구성 요소는 연결자를 통해 서버에 요청을 보내며, 서버는 해당 요청을 거절하거나 수행하고 클라이언트에 응답을 보낸다. 그리고 모든 통신은 클라이언트-서버 간의 일대일로 연결된다.

  • 클라이언트는 서버의 자세한 사항에 대해서 신경 쓸 필요 없이(e.g., 데이터베이스) 제공되는 인터페이스를 통해 접근하여 응답을 받는다. 대신 자신의 Context를 관리한다.
  • 서버는 클라이언트의 상태를 신경쓰지 않고 제공한 인터페이스에 대한 처리만 담당하여 요청이 들어올 때 그에 맞는 응답을 제공한다.

이러한 분리를 통해 Server-Client의 의존성을 줄이고 각각의 기능에 집중할 수 있다.


Stateless

각각의 요청 시에 클라이언트의 컨텍스트가 서버에 저장되지 않는다. 그렇기 때문에 위에서 언급한 자기 서술형 메시지가 지켜져야한다. 이 조건을 지킨 서버는 요청에 대한 처리만 하면 되기 때문에 구현이 단순해 진다. 또한 URI에 해당 내용을 포함시키지 않음으로써 Caching 사용 범위가 넓어질 수 있다.

상태에 대한 정보는 클라이언트가 가지고 있고 서버는 전혀 신경쓰지 않는다. 만약 어떠한 상태가 너무 중요한 나머지 서버에 두어야 할 경우에는 Resource에 추가하는 것을 고려한다.


Cacheable

자기 서술형 메시지 덕분에 각각의 요청에 대한 응답은 그 자체로 해석이 가능하다. 그렇기 때문에 독립적으로 처리가 가능한데, 이로 인해 Caching이 가능해진다. 다른 상황에 영향을 받았다면 Caching을 했을 경우 잘못된 결과가 나올 수 있다. 그 네트워크를 사용하는 비용이 가장 오래 걸리므로 이를 줄이는 것이 애플리케이션 성능을 향상시키는 좋은 방법이 될 수 있다.

# 첫번재 요청
GET /v2/tasks/2
# Reponse
200 OK
Last-Modified: Sun, 03 Apr 2016 16:09:23 GMT

# 두번째 요청
GET /v2/tasks/2
If-Modified-Since: Sun, 03 Apr 2016 16:09:23 GMT
# Reponse
304 Not Modified

# 기존의 데이터를 그대로 사용한다(이건 구현에 따라서 달라질 수 있다)

Layered System

서버는 클라이언트가 모르게 API 서버에 여러 계층을 추가하여 유연한 구조로 개발될 수 있다.

proxy나 gateway, 로드 밸런싱, 암호화 등의 기능들… 이해가 가질 않는다


Code on Demand(optional)

클라이언트는 리소스에 대한 표현을 응답으로 받고 처리해야 하는데, 어떻게 처리해야 하는지에 대한 Code를 서버가 제공하는 것을 의미한다. Html에서의 javascript가 가장 대표적인 예이다. 하지만 서버에서 제공되는 코드를 실행해야 하기 때문에 보안 문제를 야기할 수 있다.

권장하진 않는 것으로 보인다. 엑티브X같은 개념인거 같기도 하다..


결론

위에서 말했듯 REST라는 개념은 더 나은 web이 되기 위한 일종의 가이드 라인이다. 보다싶이.. 아주 추상적인 개념이라서 당장 RESTful api를 설계해야지 라고 생각하는 사람이라면 약간은 실망할지도 모르겠다. REST라는게 이러이러하게 짜면 된다는 명확한 표준이 있는 것이 아니기 때문에 이러한 제약 아래서 다양한 best practice들을 보고 자신만의 방법을 찾아가야 하지 않을까 생각이 든다.


reference