まめージェント

Android, GAE, AngularJSの技術ネタ中心。Twitter: @mame01112

RESTful Web APIsのまとめ

RESTful Web APIsを読んでみました。
Amazon.com: RESTful Web APIs eBook: Leonard Richardson, Mike Amundsen, Sam Ruby: Kindle Store

APIを定義するための必要なノウハウが書いてあって結構勉強になったので、
そのまとめを書いてみました。

僕の観点で書いてない部分も多少ありますが、
必要なエッセンスは抽出できているかと。

■Base URLに動詞をいれない。
・APIのURLに動詞は入れない。そうしないと、一貫性のないAPI名になり、
 ーAPIを使う人がリファレンスを読まないといけなくなる。
・その代わり、HTTPのGET, PUT, UPDATE, DELETEを使うべき。

■複数名詞 で 具体的な名前を使う。
・直感的なAPIにするには、itemなど抽象化するのではなく、
 albumやvideoなどのように、具体的な名前の方がわかりやすい
 -そうでないと、それを使う開発者が何が起こるかが理解できない。

・また、URLは、単数形でなく複数形であるべき
 -一番直感的なのは単数形のURLだが、
  複数形のモデルにアクセスするときに複数形のURLになってしまうので。
 -そうではなく、複数形のURLにしておいて、単数/複数のケースをカバーした方がシンプル。

・Foursquareは/checkins、GroupOnは/deals、Zapposは/Productになっている。

■モデル間の関連をシンプルにする
・場合によっては、一人のユーザ (ID :123)が持つメッセージ (ID :456)が持つ
 xxxが持つ・・・となり、APIがusers/123/messages/456/xxxx/・・・と
 URLがひたすら長くなることがあるが、これはよくない。
 ー長くても、2階層(/resource/identifier/resource)までにとどめるべき。
 (ユーザ(ID:123)が持つメッセージ(ID:456)が・・・とやっている時点で、
 すでにそのオブジェクトを持っているハズだから)

・また、Base URLをシンプルにするのに、
 ?以下のものをオプショナルなパラメータとして使うべき。

■エラーハンドリング
・HTTPのStatus codeを使う。
 -ただし、現在HTTPで規定している70くらいのStatus codeを使うと、
 Developerに調べる手間をかけさせてしまうので、
  そこまで複雑なものにすべきではない。
  →Google GData APIは、200 201 304 400 401 403 404 409 410 500の
   10個くらいに絞っている

・また、APIの挙動は、
 -全てOK
 -Client側がおかしい
 -Server側 (API)がおかしい
 の3つに収束できるので、
・200 - OK
・400 - Bad Request
・500 - Internal Server Error
 の3つをベースとして、必要に応じて付け加えていくべき
 (ただし、多くなりすぎてはならない。具体的には8個以上)

・また、APIで返すメッセージには、できる限り多くのヒントを詰め込むべき。

■バージョニング
・バージョンがない状態でAPIを使ってはならない。APIに必須。
・vを頭につけて、Base URLの先頭に持ってくる (例えばv1/users, v2/usersなど)
・バージョンに小数点をつけてはいけない。v1.2などとすると、
 APIが頻繁にアップデートされるように見えるから。
・バージョンをアップデートしても、少なくとも1つ前のバージョンとの互換は保っておく。
・バージョンの変更によってロジックが変わる場合はBase URLの先頭にバージョンをつける
・バージョンの変更によってロジックが変わらない場合(OAuthなど)は、
 Headerにバージョンをつける。
 -ので、ほとんどのアプリではURLの先頭につけるべき。

■ページネーションとPartial response
・多くのデータを返すときは、Partial responseを使う(通信の量を減らすため)
 -使い方は、/dogs?fields=name,color,locationのような感じ。
  →この本によれば、この書き方が一番見やすいから、とのこと。
・多くのデータを返すときは、すべてのデータを返すのではなく、一部だけを返すようにすること
 -start/endやoffsetとlimitを定義したり。
 -offsetとlimitを使うのが一般的。
 -/dogs?limit=25&offset=50のような感じ。

■リソースを使わないAPI
・DBにアクセスしないことを明確にするために、URLを動詞にする(convert, translateなど)

■Attributeの命名規則
・Javascriptの命名規則がオススメ(camelCase。createdAtやmyDataなど)

■APIリクエストを1つのサブドメインにまとめる。
・APIのリクエストは、1つのサブドメインにまとめるべき
 (=2つ以上のサブドメインを使うべきではない)
 -理由は、分かりやすいから。

■例外的な振る舞い
・(この章はこの以前の章の発展として書かれているとのこと。なので、
 上記と書いていることが以前と違ったりする)
・Adobe Flashのようなクライアントだと、
 レスポンスコードが200以外だと勝手にハンドリングして、
 ユーザにエラーを表示する。
 -その結果、APIを使う開発者はエラーが起こったことを知ることができない。
・なので、Twitterがやっているように、suppress_response_codesをtrueにして使うべき。
 -Adobe Flashのようなクライアントに関しては、レスポンスコードがもはや意味をなさない。

■認証
・OAuth2.0を使うべき。その他の似たような認証は、開発者をイライラさせるだけ。

■RESTful APIを使う
・Javaのsetter/getterのようなAPiを使ってはならない。
 -これをやると、1画面作るのにもいくつもAPIを使う必要があり、開発者が困る。
・APIで依存関係を示すためには、前述のPartial response syntaxを使う。
 -/owners/5678?fields=name,dogs.nameなど。

■SDKを使う
・UI仕様の複雑さなどを解決するために、APIで何とかしようとしてはならない。
 -そのような場合は、SDKを公開すべき。

■APIのAPI Facade Pattern
・APIを作るときは、API Facadeレイヤーをつくるべき。
・作る順番:
 -1: 理想的なAPIを定義する
 -2: データのスタブを作り、APIを使う人が利用できるようにする
 -3: システムとAPIをつなげる

何か違うよー、などありましたらご連絡くださいませ〜。

※2015/03/04 加筆
OAuthがOAhtoになっていたのを修正しました。
ご指摘、ありがとうございます!