Lapis Lazuli

technical blog for web developer

RESTfulAPIの冪等性について考える

RESTAPIの各メソッドの処理には冪等性であるべきものと、そうでないものがあります。
冪等性とは。についてはwikiさんによるとこういう事だそうです。
冪等 - Wikipedia

詳しく書いてありますが、要するに「何度同じ事をしても同じ結果になるということ」です。
この「同じ結果になる」ということがRESTAPIに関しては大切で、毎回GETの結果が変わっていたらAPIとして成り立ちません。

ではよく使うCRUD処理に関して、冪等性を検証してみましょう。

GET

GETは直感的に分かる通り、冪等性であるべきメソッドです。
毎回違う結果が返ってきたらそもそも意味を成しませんね。

PUT

更新するPUTも冪等性があります。
同じリソースを同じ内容で投げて更新をかけたら、何度繰り返しても同じ状態になります。
投げるパラメータを変えない限りはずっと同じです。

DELETE

削除も冪等性があると言えます。
と、ここで疑問を浮かべる方もいるかと思います。「一度目はちゃんと削除される、二回目は既に無いのを消そうとしているから違うのでは」と。
確かにレスポンスで言えば一度目は200、二度目以降は404が返ってくると予想できます。
しかしこれは正しい状態なのです。なぜならAPIの冪等性とは「リソースの状態」に注目するからです。
特定のレコードを消すDELTEメソッドを何度投げても他のレコードは消えず、データ自体は二度目以降も同じ状態になります。
なのでこれは冪等性のある処理と言えるのです。

POST

上記の前提で話をするのなら、POSTでCREATEする動作は冪等ではない挙動と言うことができます。
毎回新しいレコードを作成するのなら、リソースの状態は変わっていきます。

API設計においてのメリット

ここまで各メソッドの冪等性について説明してきましたが、何故これが担保されていると良いのか。と疑問を抱く方がいるかと思います。
簡単に言うと、「リソースの状態を気にせずAPIを叩く事ができるから」ということになります。
例えばSNSのようなアプリでユーザーをフォローする機能があったとします。
これを冪等性がないAPIで作ると、未フォローのユーザーか、フォロー済みなのかの状態で挙動を変える必要があります。
条件分岐で未フォローなら〜とか、フォロー済みのとき〜とかつける感じですね。
2パターンくらいしかない場合ならこれでいいかもしれませんが、ここにブロック機能がついてブロックされていたら〜とか条件を追加していくと、どんどん複雑になっていきます。
そこで冪等性があるAPIだと、「リクエストを投げたらフォローする」という形になるので、仕組みがシンプルになります。
叩く側も現在の状態を気にする必要はなく、開発を進める点でもスムーズになりますよね。

まとめ

言われてみると何でもない冪等性ですが、APIにとって思いのほか外せない要素だったりしますね。
モノリシックな構造だったら確かに冪等性であるべきなのですが、複数のサービスにまたがるマイクロサービスなアーキテクチャだと必ずしもこれが正解とは言えないケースがあるようです。
マイクロサービスに関しては知見が足りないのでここでは触れませんが、いつかやってみたいなーと思っています。