WebAPIについての自分用のメモです。 「これが良さそう」というような自分の方針などをまとめています。
目次:
- このノート全体の参考になるページ
- URLはRESTful、エンドポイントは複数形にする
- サブリソースはリンクのみ提示する
- クエリストリングに配列を渡す場合は v[]=a&v[]=b&... にする
- ページネーションは page=2&per_page=100
- URLにAPIバージョンを入れる /v1
- WebAPIから返ってくるJSONの実例
- RESTfulでないものの扱い
このノート全体の参考になるページ
- 翻訳: WebAPI 設計のベストプラクティス - Qiita
- 身の丈にあったWebAPI設計ガイドラインを作った話 - Qiita
- RESTful APIのURI設計(エンドポイント設計) - Qiita
URLはRESTful、エンドポイントは複数形にする
(参考ページ1より)
例:
GET /tickets
- チケットのリストを取得するGET /tickets/12
- チケット #12 の情報を取得するPOST /tickets
- 新しいチケットを作成するPUT /tickets/12
- チケット #12 を更新するPATCH /tickets/12
- チケット #12 を部分的に更新するDELETE /tickets/12
- チケット #12 を削除する
関連データーが特定のリソースに付随してのみ存在するのであればリソースURLの下に入れてもよい。
関連データーの例:
GET /tickets/12/messages
- チケット #12 に紐づくメッセージのリストを取得するGET /tickets/12/messages/5
- チケット #12 に紐づくメッセージ #5 を取得するPOST /tickets/12/messages
- チケット #12 に新しいメッセージを作成するPUT /tickets/12/messages/5
- チケット #12 のメッセージ #5 を更新するPATCH /tickets/12/messages/5
- チケット #12 のメッセージ #5 を部分的に更新するDELETE /tickets/12/messages/5
- チケット #12 のメッセージ #5 を削除する
サブリソースはリンクのみ提示する
rest - How to handle many-to-many relationships in a RESTful API? - Stack Overflow
サブリソースはJSONに内容を埋め込まず、リンクを返す。
例: スポーツのチームと所属プレイヤーを表す情報
/api/team/0: { name: 'Boston Celtics', logo: '/img/Celtics.png', players: [ '/api/player/20', '/api/player/5', '/api/player/34' ] } /api/player/20: { pk: 20, name: 'Ray Allen', birth: '1975-07-20T02:00:00Z', team: '/api/team/0' }
クエリストリングに配列を渡す場合は v[]=a&v[]=b&...
にする
(参考ページ2より)
サブリソースをリンクにした場合、いわゆる「N+1問題」が発生する。 これは最初の1回+リンクN回のアクセスが必要になるという問題。
そこでAPIへのアクセス効率を上げるため、一度で複数のリソースIDを取得できるように考える。 たとえばクエリストリングに配列で渡す。
クエリストリングで配列を表現をするケースをざっと調べる - コード日進月歩
RailsでGETメソッドのクエリストリングで配列を渡したい時にどうするか - Qiita
以下のような配列vを考える。
["v" => ["zero", "one", "two"]]
RailsではArray.to_query
で以下のような文字列が得られ、一般的にこれが使われる。
v[]=zero&v[]=one&v[]=two
PHPではhttp_build_query
に配列を渡すと以下のようになる。
v[0]=zero&v[1]=one&v[2]=two
PHPではparse_str
でこのクエリストリングを配列に戻すことができる。
もし配列に添字が無い場合には、自動的に0からの連番とみなされる。
つまり、Rails形式も受け入れることができる。
ページネーションは page=2&per_page=100
GitHub API v3 | GitHub Developer Guideでは以下のようになっている。
page=2&per_page=100
URLにAPIバージョンを入れる /v1
APIバージョンをURLに入れてしまう。
api
という言葉自体もホスト名に入れて不要とし、いきなりv1
などとするのが簡潔に思える。
WebAPIから返ってくるJSONの実例
Introduction to Tweet JSON — Twitter Developers
RESTfulでないものの扱い
検索は /search
(参考ページ1より)
検索用には/search
というエンドポイントを作成する。
上記zipcloudのURLは次のようになっている。
http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060
集計、レポーティング
特定の集計やレポート、たとえば企業の年間売上などはサーバーで集計すると効率がよい。
集計結果自体を(更新不可能な)リソースとして提供する。
例: 売上集計のURL
/report/sales/2019 /report/sales/2019/09 /report/sales/2019/09/05
/archives/:year/:month/:day routes with REST? - Rails - Ruby-ForumによるとこのURLはRESTfulではない。 日付をよりRESTfulにするには以下のようにすべきらしい。
/report/sales/year/2019/month/9 /report/sales/year/2019/month/9/day/5