CRUDの操作をRESTで表現すると一対一で対応していないことに気づきます。RはGET、DはDELETEと考えておいて良さそうですが、CとUはPUT、POST、PATCHの3つの選択肢があり、APIを設計していると迷います。整理するためにまとめておきたいと思います。
下記の資料を参考にしました。
- http - PUT vs POST in REST - Stack Overflow
- When to use PUT or POST | - The RESTful cookbook
- GitHub API v3
基本的な考え方
- PUT: リソースの作成、リソースの置換
- POST: リソースの作成
- PATCH: リソースの部分置換
PUT
PUTはPOSTと違い、リソース名を指定して作成または更新をかけるメソッドです。PUT /articles/3421
は新規作成かもしれませんし、更新かもしれません。PUTはidempotentな操作です。何度やっても同じ結果になるような処理です。例えば、Qiitaの記事をストックする操作は何度やっても、ストックされた状態には変化がないので、idempotentです。MySQLだとREPLACEに近いでしょうか。
POST
POST /articles
すると、リソース名がサーバ側で割り振られ、/articles/3421
などが出来ます。MySQLで言ったらauto_incrementがついているカラムの値を指定しないINSERT
に近いイメージです。POSTはidempotentではない処理になります。
PATCH
リソースを部分更新するメソッドです。例えば、記事のタイトルだけを更新する、記事の本文だけを更新するといったインターフェイスを提供する場合に使います。
操作としてPOSTとPUT
リソースの読み書きだけでAPIが完結すれば上の理解で作れそうですが、APIによってはリソースにアクションがある場合があります。
例えば、GitHubで言えば、リポジトリにスターをつけることや、ブランチをマージすることがあります。この場合もやはり、idempotentであるかが判断基準になりそうです。
idempotentな操作であるGitHubのスターをつけるAPIはPUT /user/starred/:owner/:repo
になっています。一方、ブランチをマージする操作はPOST /repos/:owner/:repo/merges
になっています。
ちなみに、DELETEも操作としてはidempotentですが、リソースが無くなっている場合、2回目のDELETE
は404になるのが普通のようです。http - Is REST DELETE really idempotent? - Stack Overflow
最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローお願いします→Twitter@suin