RESTful Web API 設計

REST・RESTful な Web API の設計に関するナレッジ。

目次

RESTful な URL 設計からバックエンドの実装方針まで一覧

Rails の Scaffold などを参考にした、RESTful な URL 一覧。

Verb URL Pattern Action 備考
GET /users Index 一覧表示
POST /users Create 新規登録 (ID 自動採番)
GET /users/new New 新規登録画面を開く
GET /users/:id Show 照会画面・1件取得
GET /users/:id/edit Edit 編集画面を開く
PUT /users/:id Update 全体更新
PATCH /users/:id Update 一部更新
DELETE /users/:id Destroy 削除

フロントエンドにおける画面 URL から、RESTful な URL 設計、および、バックエンドのクラス・メソッド名やデータベース設計までを横並びにしてみると、こんな感じ。

例えば POST の時に 200 を返すか 201 を返すか、といったところなど、複数の流派が見られるモノは、そのパターンを併記している。Controller のメソッド名なんかは、一般的なフレームワークでよく見られる命名を案として掲載している。

フロントエンド RESTful API バックエンド API ビジネスロジック データベース
画面 URL パス エンドポイントパス メソッド HTTP ステータスコード Controller クラス名 Controller メソッド名 Service クラス名 Entity クラス名 テーブル名 主キー名 SQL のイメージ
/users /users GET 200 OK (0件でも空配列を返す) UsersController findAll() UserService User users id SELECT
index() UserEntity
/users/{id} /users/{id} GET 200 OK find() UserModel SELECT
404 Not Found (見つからなかった場合) findOne()
findById()
show()
/users/new /users POST 200 OK (ID 付きの登録後データを返す) create() INSERT
201 Created
/users/{id}/edit /users/{id} PUT 200 OK (更新後データを返す) update() UPSERT
201 Created (新規登録となった場合のみ) save()
204 No Content
/users/{id} PATCH 200 OK (更新後データを返す) update() UPDATE
204 No Content save()
- /users/{id} DELETE 204 No Content delete() DELETE
destroy()
remove()

RESTful な設計の前提

フロントエンドの URL 設計と RESTful API との兼ね合い

API エンドポイントパスの命名

POST・PUT・PATCH の使い分け

その他 RESTful な設計に関して

Controller クラス名との関係

Controller メソッド名は RESTful 設計とは無関係

Service クラス名はビジネスロジックとして独立させる・どちらかというとデータベース寄り

Entity クラス名

DB テーブル設計

API のバージョン番号を URL に入れるかどうか

https://example.com/api/v1/users のように、/v1 といったバージョン番号を URL に入れるかどうか。

このような意見もあるが、自分は /v1 と URL に入れることをオススメしたい。ドメイン単位の分岐は、DNS 管理、ドメインまたぎの考慮が毎度必要になって面倒が増えるので、次点としたい。

バージョン番号はメジャーバージョンのみとし、後方互換性や基本的な振る舞いを保てない時にバージョンを上げる方針が良いだろう。単純な拡張、内部実装の変更だけであれば、バージョンは上げない。

将来 /v2 が出ることはないのかもしれないが、未来のことまで設計できているワケではない中で、あえて拡張性を潰す必要もない。YAGNI (必要になった時に追加すれば良い) という考え方を勘違いしていると「要らないなら作らない方が良い」と思いがちだが、コストのかからないことであれば、拡張性のある設計として事前に取り込んでおくべきだ。

API のエラー表現

Web API としてエラーをどのように表現するべきか。

このあたりが一般的な手法となるだろうか。いずれにしても、異常系におけるエラーオブジェクトのレスポンス仕様は、システム全体で統一しておくのが大事。

異常系に対する HTTP ステータスコードは、大体こんな使い分けができていれば十分だろう。

アプリケーションにエラーを伝達するための形式が RFC7807 として定められていたりする。

その他参考文献

なかなか単一の正解はないので、有名なウェブサービスの実装を参考にし、多く採用されている事例に合わせるのが良いだろう。

その他プラクティス関連の文献。