はじめに
どうすれば、開発者に喜ばれるAPIを設計できるのか、RESTFulAPI設計のバイブル「Web API Design – Crafting Interfaces that developers love」をまとめてみます。
URLの設計方針
URLはリソースを表す
- URLはあくまでリソースを表す識別子とし名詞により表現すること
- リソースを複数形で表現すること。
- リソースに対する操作を、動詞を使ったURLで表現しないこと
- 抽象的な名詞より具体的な名詞が良い
- より多くの意味を含もうとすると items といったボンヤリした単語になる。
- items では、APIの利用者(開発者)にとって意味が分かりづらい。
例えば、以下のようなURLは適切。
- /dogs/123
- /dogs/123/age
- /dogs/123/color
リソースに対する操作をHTTPメソッドで表現する
- リソースに対する操作をCRUDの4種類に分類すること
- CRUDを4種類のHTTPメソッドに対応させること。
操作 HTTPメソッド Create POST Read GET Update PUT Delete DELETE
リソースとHTTPメソッドの組み合わせは以下のような意味となる。
リソース | POST create |
GET read |
PUT update |
DELETE delete |
---|---|---|---|---|
/dogs | dogを新規作成 | dog一覧を取得 | 全てのdogを一括更新 | 全てのdogを削除 |
/dogs/1234 | 未定義 | ID=1234のdogを取得 | もしID=1234のdogがあれば更新 | もしID=1234のdogがあれば削除 |
リソース間の関連を簡潔に表現する
- 原理主義的に全てのリソースをURLに含めるとURLの階層が深くなりがちである。
- /owners/954/dogs/123/red/runninng/park …
- リソースとパラメータを分類することでリソースを表すURLの階層を浅く保つ
- パラメータはリスエストパラメータとして表現する
- /dogs?owner=954&color=&red&state=running&location=park
エラーハンドリングをしっかりする
- API利用者にとってはAPIはブラックボックスとなる。API開発者は利用者に対してブラックボックス内部で発生した出来事を伝える義務がある。
- さらにAPI開発者に対しても以下のようなメリットが生まれる
- TestFirstな開発を進めやすくなる
- プロダクトが世に出回ったとき発生したトラブルを追跡しやすくなる
以下の2つでエラーを表現する。
- HTTPステータスコード
- HTTPレスポンス文字列
まず、以下の3つのステータスコードで済ませられないか検討する。
- 200 – OK
- 400 – Bad Request
- 500 – Internal Srver Error
必要であれば、以下から選んで上記に加える。
- 201 – Created
- 304 – Not Modified
- 404 – Not Found
- 401 – Unauthorized
- 403 – Forbidden
開発者向けメッセージ、利用者向けメッセージなどを含めるなど、レスポンス文字列を可能な限り充実させること。
バージョニング
APIの更新による後方互換性を考慮し、URLにバージョンを含めること。例えば以下の通り。
- api/v1/hoge/123
- api/2016-06-12/hoge/123
- api/hoge/123?v=1.0
旧APIをいつまで保守すべきかについて、以下のような方針を取ること。
- 少なくとも1個前は保守が必要
- 保守を停止することに対して開発者の反応を”1サイクル”見ること。
- ここでいう”1サイクル”とは、開発対象による。モバイルアプリなら短いだろうしWebアプリなら長くなる。
リソース範囲を限定する方法
開発者はいつも全てのデータを必要としている訳ではない。以下の二つの戦略で取得したい範囲を限定できるべきである。
- Partial Response戦略
- あるデータについて常に全フィールドを返すのではなく、対応するデータのみ取得できる手段を提供すること。
- リクエストパラメータに取得したいフィールドを付与することで実現すること。
- Pagenation戦略
- 1回あたりの取得量を制限できる手段を提供すること。
- 例えば 100件のデータのうち、1回あたり20件を表示できるようにしたとき、page=3,limit=20 等をリクエストパラメータに付与できること。
複数のフォーマットをサポートする
- json、xml、csvなど複数のフォーマットをサポートする
- 以下のようなURL上の表現方法がある
- クエリパラメータに付与 : /api/v1/dogs/123?alt=json
- 拡張子 : /api/v1/dogs/123.json
- jsonフォーマットが最も普及しているためjsonをデフォルトとする
- jsonフォーマットを採用する場合、属性はJavaScriptの書式(CamelCase,オブジェクトタイプによる大文字小文字制御など)に従うこと
例外的な扱い
- HTTP Status Code を利用できない環境
- HTTP Status Codeとして常に200=OKを返す
- レスポンスに StatusCode を表す属性を付与する
- PUT、DELETE等のHTTPメソッドが利用できない環境
- 全てをGETリクエストとする
- 動詞部分をクエリパラメータとする
- GET /api/v1/dogs?method=put&location=park など
認証
- RESTfulAPIの認証で一般的なOAuth2.0を採用すること
- OAuth2.0と似て非なる認証を採用するのはN.G.なぜなら
- セキュリティ的に危険だから
- 開発者が慣れていないから
何度も呼び出さないといけないAPIにしない
- 開発者がどのようにAPIを使うか想像してAPIを設計すること
- 呼出回数を軽減することを心がけるkとお
- 例えば、ほとんどのケースである条件で絞り込んだ結果が求められるのに、必ずAPI経由で絞込みを行わせるなどは避ける
- 使われ方を想定したデフォルトを設定する