APIのURIを短くする
June 8, 2017
API
URI
URL
rails
Web API: The Good Partsを読んだのでその整理
URIを短くする
APIのURI設計をしていると、親子関係があるデータを扱う時URIが長くなる
例えば
- blogが複数の記事をもつ
- 記事は複数のコメントを持つ
- コメントは複数の返信コメントをもつ
集合で表すと blogs ∋ articles ∋ comments ∋ replies
railsだと以下のようになる
$ rails routes
Prefix Verb URI Pattern Controller#Action
replies GET /blogs/:id/articles/:id/comments/:id/replies(.:format) replies#index
POST /blogs/:id/articles/:id/comments/:id/replies(.:format) replies#create
reply GET /blogs/:id/articles/:id/comments/:id/replies/:id(.:format) replies#show
PATCH /blogs/:id/articles/:id/comments/:id/replies/:id(.:format) replies#update
PUT /blogs/:id/articles/:id/comments/:id/replies/:id(.:format) replies#update
DELETE /blogs/:id/articles/:id/comments/:id/replies/:id(.:format) replies#destroy
とてもじゃないが、使えたものじゃない…
Herokuではどうしているかというと、
Limit nesting depth by preferring to locate resources at the root path. Use nesting to indicate scoped collections. For example, for the case above where a dyno belongs to an app belongs to an org:
/orgs/{org_id} /orgs/{org_id}/apps /apps/{app_id} /apps/{app_id}/dynos /dynos/{dyno_id}
つまり、ネストの深さを制限するのと親子は集合を表すのが大事
実際にやってみる
blogが複数の記事を持つものとする
集合で表すと blogs ∋ articles
articleをrailsでscaffoldすると次のリソースになる
$ rails routes
Prefix Verb URI Pattern Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
これが親子関係になると次のリソースになる
$ rails routes
Prefix Verb URI Pattern Controller#Action
articles GET /blogs/:id/articles(.:format) articles#index
POST /blogs/:id/articles(.:format) articles#create
article GET /blogs/:id/articles/:id(.:format) articles#show
PATCH /blogs/:id/articles/:id(.:format) articles#update
PUT /blogs/:id/articles/:id(.:format) articles#update
DELETE /blogs/:id/articles/:id(.:format) articles#destroy
が、ネストが深い
ここでHerokuのURI設計を参考にするとこうなる
$ rails routes
Prefix Verb URI Pattern Controller#Action
articles GET /blogs/:id/articles(.:format) articles#index
POST /blogs/:id/articles(.:format) articles#create
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
新規作成と一覧取得は親子関係の状態で持ってくる, 作成するのでそのまま。
詳細取得と更新、削除は一意な値で判断して編集するので、省略できる。
blogに属さない記事は存在しないので、こんな感じで良さそう。