Martin Fowler氏は、新しい 論文 で、Leonard Richardson氏によって開発された RESTful成熟度の3レベルモデル を使って、 webスタイルのシステムを説明している。
Fowler氏によれば、成熟度モデルの開始点は、リモートなやりとりための純粋な通信システムとして、HTTP を使うことである。この場合、1つのサービスがある-予約サービス、これは1つのメソッドコール(彼の例では、POST)とXML入/出力を使って、特定のリクエストとリプライを交信する。
空いている医者に予約する場合には、リクエストが必要で:
POST /appointmentService HTTP/1.1
<openSlotRequest date = "2010-01-04" doctor = "mjones"/>
これにリプライを返す:
HTTP/1.1 200 OK
<openSlotList>
<slot start = "1400" end = "1450">
<doctor id = "mjones"/>
</slot>
<slot start = "1600" end = "1650">
<doctor id = "mjones"/>
</slot>
</openSlotList>
空いているスロット(時間帯)に予約をするには、次のリクエストが、必要:
POST /appointmentService HTTP/1.1
<appointmentRequest>
<slot doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointmentRequest>
すると次のようなリプライが来る:
HTTP/1.1 200 OK
<appointment>
<slot doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointment>
REST (Level 1)に移行には、リソースを使い始める。1つのサービスのエンドポイントに全てのリクエストをするのではなく、RESTの場合には、個々のリソースを扱う。前の例では、医者と予約スロットがリソースである。
リソースを使うとリクエストを分割できるようになる。各リソースは、あるセットの機能をサポートしている。またリクエストを単純化できる-あるリソースを参照することで、リクエスト情報のあるものを暗黙に作れる。氏によると:
私のようなオブジェクト人間には、これは、オブジェクト識別の概念です。エーテル中の関数を呼んで引数を渡すのではなく、特定のオブジェクに対して、他の情報のための引数を提供しながらメソッドを呼ぶのです。
この場合、最初のクエリは、医者リソースに投げられる(医者の名前は、もうリクエストには無く、リソース定義にある):
POST POST /doctors/mjones HTTP/1.1
<openSlotRequest date = "2010-01-04"/>
今やリプライは、直接アドレス指定できるリソースとして各スロットを返す:
HTTP/1.1 200 OK
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650"/>
</openSlotList>
slot IDが、予約リクエストをポストするのに使うことができる:
POST /slots/1234 HTTP/1.1
<appointmentRequest>
<patient id = "jsmith"/>
</appointmentRequest>
これが似たようなリプライを返すべきで:
HTTP/1.1 200 OK
<appointment>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointment>
レベル1では、主にシステムの分解を目指しているが、レベル2は、コールに使われるHTTP verbについてで- HTTP verbをそれらがHTTP 自身の中で使われるのにできる限り近いように、マッピングすることを意図している。
レベル2では、[クエリ]リクエストにGETを使うことが、極めて重要 です。HTTP は、 GET を安全な操作、いかなるものの状態にも意味のある変化をもたらさない、と定義しています。このために、GETをいかなる順番で、何回呼んでも毎回同じ結果が得られます。このことの重要な結果が、リクエストのルーティングに参加するものは、キャッシュが使えることです。webが機能すると同じぐらい、キャッシュは、webを機能させるのに貢献している重要な要素です。 HTTPは、コミュニケーションの全参加者が使えるキャッシングをサポートする様々な方法があります。 HTTPのルールに従うことにより、我々は、その能力を利用することができます。
この場合のリクエストは:
GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1
リプライは、POSTの場合と同じである:
HTTP/1.1 200 OK
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650"/>
</openSlotList>
予約を確立するには、ステートを変更するHTTP verb、POSTあるいはPUTを使うべきである。この論文では、 Fowler氏は、POSTを使っている:
POST /slots/1234 HTTP/1.1
<appointmentRequest>
<patient id = "jsmith"/>
</appointmentRequest>
これは、こんな感じのものを返すことができる:
HTTP/1.1 200 OK
<appointment>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointment>
氏によれば、POSTを使う際の重要な点は:
...[リクエストの結果]を示すHTTPレスポンスコードを使って...エラーレスポンスを含む以外に、 200という返り値を使うより、レベル2では、このようにある種のエラーレスポンスを明示的に使います。どのコードを使うかを決めるのは、プロトコル設計者しだいですが、エラーが発生したら2xx以外のレスポンスであるべきです。レベル2では、HTTP verbと HTTPレスポンスコードが導入されています。webの存在によってサポートされている重要な要素は、安全(例えば GET)と安全でない操作の間にある強い分離とそれといっしょにステータスコードを使って、遭遇したエラーの種類を知らせるのを助けることです。
氏は、レベル2には、一貫性を欠いている部分があることも注意している:
RESTの支持者は、すべてのHTTP verbを使うことを話題にしています。彼らはまた、RESTは、webの事実上の成功から学ぶ努力をしている、と言うことによって彼らのアプローチを正当化しています。しかし、 WWWは、PUT あるいはDELETE を実際のところ、そんなに使っていません。PUT と DELETE をもっと使う賢明な理由がありますが、webの存在証明は、その理由の1つにはなっていません。
最後に、レベル3では、しばしばHATEOAS (Hypertext As The Engine Of Application Stateアプリケーション状態エンジンとしてのハイパーメディア )と呼ばれるものが、導入されている。 RESTでは、すべてのリソースは、リソースIDを返す代わりに 、固有のURIを持ち、コンシューマがこのURI自体を計算できるようにしているので、レベル3のレスポンスは、直接リソースのURIを返して、それを次の操作に使うことができるようにしている:
HTTP/1.1 200 OK
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450">
<link rel = "royalhope.nhs.uk/linkrels/slot/book" uri = "slots/1234"/>
</slot>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650">
<link rel = "royalhope.nhs.uk/linkrels/slot/book" uri = "slots/5678"/>
</slot>
氏は、次のように説明している:
ハイパーメディア・コントロールのポイントは、次に何ができるかと、そうするのに操作する必要があるリソースのURIを教えてくれることです。我々の予約リクエストをどこに投げるべきかを我々は、知る必要がなく、レスポンス中のハイパーメディア・コントロールが、どうするのかを教えてくれます。ハイパーメディア・コントロールの明白な恩恵は、サーバがクライアントに気づかれずにURIスキームを変えられることです。別の恩恵は、クライアント側の開発者がプロトコルを調べる助けになることです。クライアント側の開発者に、linkは、次に何が可能かについてのヒントに与えますから。
氏が示したモデルは、RESTサービスに3つの設計技法(レベル)を定義している:
- レベル1は、分割と統治を使い、大きなサービスのエンドポイントを複数のリソースに分割することによって、複雑さを処理するという問題に取り組んでいる。
- レベル2は、HTTP verbの標準セットを導入し、不必要な変形を取り除き、似たような状況を同じように処理している。
- レベル3は、発見性を導入して、プロトコルをもっと自己説明する方法を提供している。