有名な書籍Webを支える技術で紹介されていた「べき等」と「安全」について自分なりに考察してみました。
Restの実装経験は業務でないですが、今後実装経験を積んでいくにつれて
必要な知識になりそうだと思い、学習しています。
学習途中で、「べき等」と「安全」という概念が書籍で紹介されており、
その内容について考察してみました。
「べき等」と「安全」
RESTに用いられるHTTPメソッドには「べき等」と「安全」という考え方があるようで、
べき等
ある操作を何回行っても結果が同じであること
e.g) 何度UPDATE処理をしても、すで更新済みの内容であればデータは変化しない
DELETEも同様に、一度削除すればずっと削除された状態が保持されるのでデータは変化しない
安全
操作対象のリソースの状態を変化させないこと
e.g) SELECTの場合、データに変化を与えず取得のみを行う
上記をまとめると、以下のように分類できる
書籍では、HTTPメソッドごとに下記のように分類されている(p101参照)
————————————————————————
HTTPメソッド 性質
GET、HEAD べき等かつ安全
PUT、DELETE べき等だが安全でない
POST べき等でも安全でもない
————————————————————————
考察
なぜこのような「べき等」と「安全」という概念が存在するのか考察してみる。
そもそもデータ操作の種類に着目すると2パターンの動きが考えられる
- データを取得する
- データに変化を加える
上記の操作に行うにあたって必要な考えとして
(1)では、データに対する取得のみを行う → GETメソッドで再現する
(2)では、データ挿入(INSERT)する、データを更新する(UPDATE)、データを削除する(DELETE)の3パターンにさらに分類できる
ーーさらに更新(UPDATE)では、データをある一定の値に留まらせるための更新(※1)と
ーーデータを加算的に常に変化させる操作を加えるもの(※2)が存在する
(2)の場合でデータを削除(DELETE)する場合はHTTPメソッドのDELETEに該当することは一目瞭然だが、
INSERT/UPDATEと対になるHTTPメソッドは何かということについては不明瞭である
ここで、HTTPメソッドの本質的な概念を振り返る
INSERT/UPDATEをする際に、用いられるHTTPメソッドはPUT/POSTに該当するが
PUTの概念である「べき等だが安全でない」に従わなければならない
とすれば、PUTによるデータ操作でINSERT/UPDATE処理を行った場合、
2度目以降の同様のデータ操作は何度行っても同じ結果にならなければならない
つまり、上記(※1)に該当する操作としてPUTを用いることがREST処理において
正しい使い方だと考えられる
POSTについては、「べき等でも安全でもない」に従う必要がある
PUTとの違いは「べき等でない」ことである。
これは上記(※2)に該当することがわかる。
つまり、POSTによるデータ操作は常にデータに変化を加え続けるという性質のもと利用されなければならない
INSERT処理を行った場合、次回に同じ内容のリクエスト処理がきても
新たにレコードを追加してまたINSERT処理を行う。
すでにINSERT済みのデータにUPDATE依頼がきたら
対象のデータの状態を変化させる必要がある。
以上の内容をまとめるために、[考察]の仮定を再度振り返る。
- データを取得する SELECT(GET) ・・・対象のデータの取得のみを目的とする操作
- データに変化を加える ー DELETE(DELETE) ・・・ 対象のデータの削除をのみを目的とする操作
ー ー INSERT/UPDATE(PUT) ・・・データをある一定の値に留まらせる操作(更新/挿入)
ー ー INSERT/UPDATE(POST) ・・・データを加算的に常に変化させる操作を加える操作(更新/挿入)
これら全てのデータの基本操作を概念化したものを「べき等」と「安全」と呼んでいるのだと思われる。
つまり、HTTPメソッドにおいてデータ操作を行う際は、
そのデータ操作の概念として常に下記に分類される方法によってなされなければならないということだと考えられる。
————————————————————————
HTTPメソッド 性質
GET、HEAD べき等かつ安全
PUT、DELETE べき等だが安全でない
POST べき等でも安全でもない
————————————————————————
実際の現場では、POSTはPUTの操作も兼ねて使用されることが非常に多いと思うが、
その背景としてクライアントソフト側でAjaxという技術や概念がなかったころ、
Form形式でデータの送信を行う必要があり、Form形式のよるデータ送信の規定として
GET/POSTとしか使用できないという規制(p98)があったため、データ操作の基本概念を無視した
実装がされるようになったのではないかと考えています。
あるいは、PUTという考え方自体が不要で、
データ操作の分類として無視できず存在してしまうから
PUTという操作を概念化させているのかもとも思いました。
この辺の内容については、今後調べていきたいです。
また、RESTの実装にあたって、この「べき等」、「安全」のルールを守って実装することを
今後心がけようと思います。