ROA(Resource Oriented Architecture)について。
次の本を参考に勉強してみた。
参考図書
RESTful Webサービス
ROAの基本
アプリケーションを動作と名詞(リソース)で考える。
リソースは特定のデータ、データの演算結果、状態、ユーザーアカウントなどである。
URIに動詞を含めてはならない。
リソースはHTTPメソッドを使用してのみ操作できる。
アドレス可能性
リソースはアドレス(URI)で一意に表現する。
1つのURIが複数のリソースを示してはいけない。
リソースを特定の言語や特定のフォーマットで取得したい場合は「Accept-Language」や「Accept」、または「Media-Type」を使用する。このようにリソースの表現方法が複数ある場合はレスポンスヘッダに「Content-Location」を設定して表現に依存しないベースとなるURI(あたはデフォルトフォーマットを返すURI)を示す。
ステートレス
サーバーはリソースの状態を管理するが、クライアントの状態は記憶しない。クライアントは自分の状態の変化をPOST、PUTを用いてサーバーに送信することで(その都度)教える。これによってサーバーはクライアントの状態を気にせずに負荷分散や冗長化ができる。
統一されたメソッド
GET(取得)、HEAD(参照)、POST(変更)、PUT(新規追加)、DELETE(削除)を介してのみリソースの動作を規定する。あまり使用されないが、PUTはリソースが無い状態からの新規追加である。これはクライアントが最終的なURIを知る事ができる場合のみ使用可能である。
安全性
GETとHEADはリソース状態を変更してはならない。
べき等性
GETとHEADとPUTとDELETEは何度実行しても結果が同じでなければならない。これにより、回線が途中で途切れても同じリクエストを安全に送信することができる保証をする。
POSTの拡張
POSTはURIまたはエンティティボディに拡張情報を格納してRPCメソッドとして使える。だが、なるべくそうするべきではない。
POSTはPUTやDELETEをサポートしていないサーバーで、メソッドをオーバーロードするのに使用できる。また、URI表現が長過ぎる場合にに「method=GET」でGETメソッドをオーバーライドできる。サーバーサイドの事情を回避するやむを得ない場合のみそうするべきである。
リソース指向が難しい場合
HTTPのメソッドのみを介してリソースへアクセスさせることが難しいと感じる時は、リソースの新しい定義を増やすことで対応する。
AliceとBobがサービスのリソースであるとしよう。(中略)ある日、AliceとBobが結婚する。クライアントはAliceのURIにPUTリクエストを送信し、Bobと結婚したことを示すようにAliceの状態を変更した後、BobのURIにPUTリクエストを送信し、BobがAliceと結婚した事を伝える。この場合は作業が二つに分かれるので、あまり満足のいく方法ではない。クライアントがAliceのURIにPUTリクエストを送信した後、BobのURIにPUTリクエストを送信するのを忘れるかもしれない。その場合、AliceはBobと結婚しているが、BobはAliceと結婚していないことになる。
そうではなく、この2つのリソース間の関係、すなわち結婚を3つ目のリソースとして扱うべきである。237ページより引用
つまり、迷ったらリソースにする。
どうしても苦しい場合はPOSTメソッドのオーバーロードで対応する。
バージョニング
APIのバージョンはURIで管理する。
v1/resource
v2/resource
またはホスト名で管理する。
v1.example.com
v2.example.com
ただし、Rebuild: 35: You Don't Need API Version 2 (Kenn Ejima)でも語られているように、これは賛否両論ある。内部での分岐、キー名の変更などでギリギリまで対処する必要もある。
URIは意味を持つべきか
この本のP246には、面白い議論がある。
URIにリソースの状態まで含めてしまうと、状態が変わった時(たとえば人の名前が変わった時)にそのURIが無効になってしまう。
Jakob Nielsenは意味のあるURIを主張しているが、Tim Berners-LeeはURIの不透明性を主張している。つまり、決して変化しない「意味のない」URIである。「逆参照しているのでなければ、ほかの情報を取得するためにURI文字列の内容を調べるべきではない」。つまり、URIはリソースの名前として使用できるが、URIを分解してその意味を調べるべきではなく、URIを変化させればリソースを変更できると考えるべきではない。URIに実際に意味があるように見えたとしても、何も推測することはできない。
P246より引用
この後、筆者は言葉を濁しつつもほとんどの場合はユーザーインターフェースとして機能する意味のあるURIを支持する、としている。