😶

API設計とURLの命名規則

2022/08/03に公開

結論

完全リソースベースの命名、完全コマンドベースの命名ではなく、リソースベースにうまくコマンドを取り入れるとAPIが設計しやすい。またコマンドが増えすぎたときは、そこにリソースが隠れていないか探し、APIのリファクタリングを行う。

Restの流行とリソースベースの命名規則

Railsの影響でRestfulが流行って、URLをリソースの階層とそれに対するHTTPメソッドで表現する方法が流行った。

例えばユースケース

  • 猫一覧表示
  • 猫新規作成
  • 猫情報更新
  • 猫情報削除

の場合はつぎのようになる。

- #GET /cats
- #POST /cats 
- #PUT /cats/:id 
- #DELETE /cats/:id 

しかし、これを習ったとき、理解したつもりになっても、実際に実装しだすと、そう簡単には物事は進まなくなる。

たとえば猫のステータスをACTIVE状態にしたいAPIがあったとき、どう表現すべきか?

無理やりリソースで考えると次のようになる。

ステータスの変更と考えて
- #PUT /cats/:id 

もしくは、ステータスが`ACTIVE`なリソースを定義して
- #POST /active-cats

putで単純に終わらせてしまうのも、単純化しすぎだし、意図が消えてしまう。
また、このためだけにactive-catsというリソースを定義するのも、無駄にコントローラーが増えて大変そう。

コマンドベースの命名規則

ここでいうコマンドベースとはすべてPOSTメソッドを使って、やりたいこと(コマンド)をURLで表現する方法。

- #POST /get-cats
- #POST /create-cats 
- #POST /update-cats 
- #POST /delete-cats 

リソースベースほど整理できない。

リソースベースとコマンドの融合

API設計をしていると経験を積んだ人ほど無意識にやってるかも。リソースベースの問題点は更新(UPDATE, PUT) の扱いにくさにある。そこで、基本的なリソースベースな書き方は維持しつつ、更新の派生的な特殊なユースケースに対してコマンドにする。

一般的なユースケース

  • 猫一覧表示
  • 猫新規作成
  • 猫情報更新
  • 猫情報削除
- #GET /cats
- #POST /cats 
- #PUT /cats/:id 
- #DELETE /cats/:id 

「猫のステータスをACTIVE状態にしたいAPI」などの特定のユースケース。

- #PUT /cats/:id/activate

これは、オブジェクト指向的な考え方(まず物があって、それに対していくつかメソッドがある)にも相性がよい。

リソースベースとコマンドの融合の注意点

コマンドではなく、リソースに変えたほうがいいときもある。

例えば、ACTIVE状態の猫に対して複数のAPIがあったとき、こうするのは整理できていない。

- #PUT /cats/:id/do1-for-active
- #PUT /cats/:id/do2-for-active
- #PUT /cats/:id/do3-for-active

むしろ、こういうときは新しいリソースを見出したほうが、APIも作りやすくなる。

- #PUT /acitve-cats/:id/do1
- #PUT /acitve-cats/:id/do2
- #PUT /acitve-cats/:id/do3

Discussion