How to GET a Cup of Coffee
지난 10월 짐(Jim), 사바스(Savas), 이안(Ian)은 “한 잔의 커피를 GET하는 법“이라는 제목의 매우 훌륭한 글을 썼다. 저자들은 이 글에서 스타벅스의 예를 통해 어떻게 기업 워크플로우를 RESTful한 방법으로 구현할 수 있는지 설명했다. 저자들은 협동(coordination)을 위한 응답 코드(response code)의 사용, 일관성(consistency)을 위한 ETags의 사용, 확장성(scalability)과 탄력성(resiliency)을 위한 캐쉬의 사용 등 몇 가지 유용한 아이디어를 제공했다.
하지만, 몇 가지 생각해 볼 점이 있어 아래에 적는다.
리소스의 상태와 어플리케이션의 상태는 따로 설명되어야 한다.
GET과 HEAD는 상태 변이(state transition)를 일으키지 않는 특별한 경우이다.
위에 인용한 문장처럼 GET과 HEAD는 리소스의 상태를 바꾸지는 않지만 어플리케이션의 상태 변이를 일으킨다. 웹 브라우저를 생각해보자. 웹 페이지의 링크를 클릭하면 웹 브라우저는 해당 URI가 가리키는 리소스의 표현(representation)을 가져오고(GET), 한 상태에서 다른 상태로 이동한다. 이것이 바로 웹 브라우저에서 이 페이지를 볼 수 있는 이유이다.
미디어 타입만 알면된다.
이 글의 <next/> 태그는 기본적으로 하이퍼미디어에 대한 것이다. 저자들은 스타벅스가 사용한 XML 파생물(dialect)이 다른 리소스에 대한 정보를 포함할 수 있다고 했다. 하지만 내 생각에 포함될 필요가 있는 정보는 URL 같은 그 리소스에 대한 식별자(identifier) 뿐이다.
그리고 이 경우에 “하이퍼텍스트를 어플리케이션 상태의 엔진으로(Hypertext As The Engine Of Application State)”라는 말이 적용된다. 다음 상태는 오직 리소스의 표현에 의해서만 정의될 수 있다. 하나의 리소스는 여러 형태의 미디어 타입을 따르는 여러개의 표현을 가질 수 있고, 각 미디어 타입은 각각의 처리 모델을 정의한다. 또 각 리소스의 표현은 그 자체로 의미하는 바를 기술한다(즉, 자기설명적(self-describing) 리소스 표현).
그래서 난 왜 추상적인 상태 변이를 위한 별도의 네임스페이스나 표준이 필요한지 모르겠다. 상태 변이는 REST의 기본적인 개념 중 하나이다. 만일 그러한 네임스페이스(예, http://example.org/state-machine)가 존재한다 해도 여전히 각 변이 타입에 대한 의미는 또 다른 네임스페이스에 정의되어야 한다(예, http://starbucks.example.org/payment). 게다가 표현이 자기설명적이라면 서버와의 협상을 통해 표현의 타입을 알 수 있고, rel 속성으로 사전에 타입을 정의할 필요는 없어진다. 그래서 다음 코드처럼 특정 전이 타입을 위한 태그를 만들 수 있고, 그 의미는 해당 태그에 의해 정의된다. 그리고 이 태그를 정의하고 있는 네임스페이스는 재사용이나 표준화가 가능하다.
<order xmlns="http://starbucks.example.org/"> <drink>latte</drink> <additions>shot</additions> <cost>4.00</cost> <payment>https://starbucks.example.com/payment/order/1234</payment> </order>사람을 위한 웹도 RESTful하다.
소비자 어플리케이션(consumer application)인 웹 브라우저는 단순히 HTML을 화면에 표시한다. 그리고 상태 기계(state machine)인 사용자는 GET과 POST를 통해 링크를 따라 이동한다. 웹 기반의 통합도 이와 비슷하다. 단, 이 경우 서비스와 그 소비자는 상호작용을 위한 프로토콜 뿐 아니라 표현의 포맷과 의미에 대해서도 서로간의 합의가 필요하다.
내가 생각할 때 위의 문장은 다음의 문장과 다소 모순된다.
사람을 위한 웹에서 소비자와 서비스는 HTML을 표현 포맷으로 사용한다. HTML은 자신만의 의미를 갖고 있고, 이 의미는 모든 브라우저가 이해하고 받아들인다.
따라서 내 생각에 웹 기반의 통합도 어떠한 예외 없이 사람을 위한 웹과 동일하게 동작한다.
그 외 몇 가지…
- 나 또한 부분 갱신을 위한 PUT의 사용에는 반대한다. POST나 PATCH가 좀 더 나은 대안으로 보인다.
- OPTIONS나 Expect/Continue의 사용이 항상 이득이 되는지는 의문이다.
- “URI는 상태 기계의 변이를 나타낸다”는 표현은 너무 단순하고 부정확하다.
- 나는 수정이 가능한 리소스라 해도 오직 하나의 주소만을 가져야 한다고 생각한다.
- XML에서는 마이크로포맷을 사용할 필요가 없다. RDF를 쓰는것은 어떨까?
- URI 템플릿에 대한 저자들의 의견에 전적으로 동의한다.
- 우리는 웹에서의 진화(evolution)나 부분적 이해(partial understanding)의 중요성을 이해해야 한다.
아마 저자들은 내가 위에서 언급한 내용을 잘 알고 있을 테지만, 나를 포함한 초보자들에게는 오해의 여지가 조금 있다. 어쨌든 이 글은 매우 훌륭하고 시간을 투자해 읽을만한 가치가 충분하다.








3 Comments
jump to comment form | comments rss | trackback uri
Its great to see coherent workflow/process REST examples these days, really focusses the mind on solving real enterprise problems.
”
latte
shot
4.00
https://starbucks.example.com/payment/order/1234
”
I see what you are saying but if there are a lot of state transitions involved won’t this get confusing to the client?
They may understand what following the payment link means but they won’t know if its a valid transition from the current state.
Argh, that last post didn’t work too well. I’ll try again.
Its great to see coherent workflow/process REST examples these days, really focusses the mind on solving real enterprise problems.
“So, like the below, we can define a tag for a specific type of transition and its semantics can be defined by the tag itself”
I see what you are saying but if there are a lot of state transitions involved won’t this get confusing to the client?
They may understand what following the payment link means but they won’t know if it’s a valid transition from the current state.
Hi Colin,
To follow links, even if you use a more general vocabulary like <next/>, you still need to distinguish among the different state transitions based on the semantics of each transition.
And I think if there is a link in the representation, it means following the link is a valid state transition. If it’s not valid, the representation shouldn’t have the link in it.
Have your say
XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>