冪等と安全に関する誤解

## 1. 概要
この記事では、HTTP における「冪等と安全に関する誤解」について投稿します。
この「冪等」と「安全」を的確に理解することは、特に Web API 設計においては、とても重要なポイントといえるでしょう。

## 2. はじめに
私は、OSS プロジェクト「[WARP-WG](https://warp-wg.org/)」の Founder を務めつつも、REST API デザインパターンを踏襲した複数の Web API サービスの技術設計者でもあり、ポスト REST API の提唱者でもあり、複数の Web API サービスのコンサルティングも務めてきました。
その中で、この「冪等」と「安全」については、多くのご質問とご相談を受けてきました。
また、REST API デザインパターン界隈においても、特に「冪等」のセマンティクスについては、今までよく議論されてきたトピックの一つでもあります。
しかし「冪等」について言及される場合には、「安全」についても同列で言及されたほうが、私の今までの Web API サービス設計や、Web API コンサルティングの経験則からも、より良く理解が進むのではないかと思います。
そこでこの記事では、HTTP における「冪等」と「安全」のセマンティクスと補足的に「キャッシャブル」や「副作用」について解説しながら「冪等と安全に関する誤解」について解いていこうと思います。

| メソッド | 冪等 | 安全 | キャッシャブル | リファレンス |
| --- | --- | --- | --- | --- |
| HEAD | o | o | o | [RFC-7231 4.3.2](https://tools.ietf.org/html/rfc7231#section-4.3.2) |
| GET | o | o | o | [RFC-7231 4.3.1](https://tools.ietf.org/html/rfc7231#section-4.3.1) |
| POST | x | x | △ | [RFC-7231 4.3.3](https://tools.ietf.org/html/rfc7231#section-4.3.3) |
| PUT | o | x | x | [RFC-7231 4.3.4](https://tools.ietf.org/html/rfc7231#section-4.3.4) |
| PATCH | △ | x | x | [RFC-5789](https://tools.ietf.org/html/rfc5789) |
| DELETE | o | x | x | [RFC-7231 4.3.5](https://tools.ietf.org/html/rfc7231#section-4.3.5) |
| CONNECT | x | x | x | [RFC-7231 4.3.6](https://tools.ietf.org/html/rfc7231#section-4.3.6) |
| OPTIONS | o | o | x | [RFC-7231 4.3.7](https://tools.ietf.org/html/rfc7231#section-4.3.7) |
| TRACE | o | o | x | [RFC-7231 4.3.8](https://tools.ietf.org/html/rfc7231#section-4.3.8) |

## 3. 副作用
冪等、安全、キャッシャブルのセクションに入る前に、まず「副作用」について解説します。

2014 年 6 月に廃止された [RFC-2616 の「9.1 安全と冪等メソッド」のセクション](https://tools.ietf.org/html/rfc2616#section-9.1) では、「副作用（side effects）」という表現が使用されてきましたが、多くの方は、この「副作用」のことを、「リソースの状態の変化」と解釈されてきたことと思います。[ [^1] ]
特に関数型プログラミングにおいては頻出する表現ですが、ソフトウェア工学的にも

> コンピューターの論理的な状態を変化させ、以降の結果に影響を与えること [ [^2] ]

とされています。
しかし、HTTP の「冪等と安全」の解釈の混乱を招いてきた要因 [ [^3] ] の一つのは、この「副作用」の表現方法が適切ではなかった、ということではないでしょうか。
以下では、その理由について解説しますが、その必要のない方はこのセクションはスキップしてください。

まず、[RFC-2616 の「9.1.1 安全メソッド」のセクション](https://tools.ietf.org/html/rfc2616#section-9.1.1) において、

> 本質的に、サーバが GET リクエストを実行した結果として__副作用__を起こさないという事を保証するのは不可能であり、事実、いくつかの動的なリソースはそれが特徴であると考えている。ここで特に区別すべきなのは、ユーザが__副作用__を要求しなかったという事であり、それゆえにそれらに対しては責任をもてない。

と、「副作用」という言葉が使われてきましたが、その前段の

> 特に、GETメソッドとHEADメソッドには、__検索以外のアクションを実行する意義があるべきではない__という規約が確立されています。

という文の「意義があるべきではない」という文脈により、この「副作用」とは「意義があるべきではない作用 = 検索以外の作用」という意味論であろうと解釈をすることはできるでしょう。
更には、[RFC-2616 の「9.1.2 冪等メソッド」のセクション]((https://tools.ietf.org/html/rfc2616#section-9.1.2)) においても、

> メソッドは（エラーや有効期限の問題を除けば）、N > 0 の同一リクエストの__副作用__が、単一リクエストの場合と同じであるという場合は、「冪等性」の特性を持つこともできる。

と、「副作用」という言葉が使われてきました。
しかし、ここで、違和感を覚えた方も多いのではないでしょうか。
それは、ここでいう「副作用」の説明、もしくはその対となるべく「主たる作用」の説明が本セクションには無く、また [RFC-2616]((https://tools.ietf.org/html/rfc2616)) 全体においても、その定義が全くなされていないからではないでしょうか。
そこで、セクション違いですが、前述の「安全メソッド」セクションにおける「副作用」の解釈を引用してみると

> メソッドは（エラーや有効期限の問題を除けば）、N > 0 の同一リクエストの__「検索以外の作用」__が、単一リクエストの場合と同じであるという場合は、「冪等性」の特性を持つこともできる。

となります。
しかし、この場合でも「検索以外の作用」とは、何の作用を指しているのか、具体的な説明がないことから、「冪等」の定義が不明瞭となり、この引用でも適切ではないことが分かります。
本来「副作用」には、因果律の原則から、その因果関係にある「作用因」と、依属の関係にある「主たる作用」が存在します。

```
         < - （因果関係）
「作用因」 + - > 「作用」
         |       ↑ （依属関係）
         + - > 「副作用」
         < - （因果関係）
```

しかし、この「冪等メソッド」のセクションでは、ここでいう「副作用」の説明だけでなく、それに対する「作用因」や「主たる作用」の説明がありません。
もし [RFC-2616](https://tools.ietf.org/html/rfc2616) が、局所で使用するワードが、参照の明記なくドキュメントの広範にわたってそれぞれの文脈に依属する関係だと仮定しても、それは技術標準化文書の意味論としては適切ではないでしょう。
このような文脈では説明のつかない「副作用」の表現方法になってしまった背景は、冒頭でも触れたように、特に関数型プログラミングや一部の情報工学分野において「副作用 = 状態の変化」という概念が存在するため、その領域固有の狭義をそのまま使用してしまった、ということが考えれれるでしょう。
そこで、その概念を先ほどの文章に当てはめてみると

> メソッドは（エラーや有効期限の問題を除けば）、N > 0 の同一リクエストの__「リソースの状態の変化」__が、単一リクエストの場合と同じであるという場合は、「冪等性」の特性を持つこともできる。

と、ようやく意味論として成り立つことがわかります。
（「状態の変化」の詳細につきましては、また別の機会がありましたら解説します。）
これを更に「安全メソッド」セクションの文章に適用してみると、

> 本質的に、サーバが GET リクエストを実行した結果として__「リソースの状態の変化」__を起こさないという事を保証するのは不可能であり...

と、こちらも意味論として成り立つことがわかります。
しかし、一般的な概念として「副作用 = リソースの状態の変化」という意味論は存在しないことから、このような局所的な領域における概念を知らない技術関係者が、この説明を解釈しようとしたときに違和感や誤解が生じる状況が生まれてしまったと推測することができます。
更に、もう一つ HTTP の「冪等と安全」の解釈の混乱を招いた決定的な要因として考えられるのは、本当に

> メソッドは（エラーや有効期限の問題を除けば）、N > 0 の同一リクエストの__「リソースの状態の変化」__が、単一リクエストの場合と同じであるという場合は、「冪等性」の特性を持つこともできる。

とするならば、GET や HEAD メソッドは「リソースの状態の変化」を伴わないため、__「GET や HEAD メソッドは冪等ではなくなる」__という、完全なロジックの破綻が生じていることです。
以上のことからも、「副作用」という意味論が、局所的な概念を前提に表現されたことによって、文脈のあらゆる箇所に矛盾や誤解が生じやすい状況になっていることが分かります。

しかし、[RFC-2616](https://tools.ietf.org/html/rfc2616) を廃止した [RFC-7231]((https://tools.ietf.org/html/rfc7231)) においては、「作用（this effect）」と「副作用（side effects）」という言葉によって表現されるようになりました。
[RFC-7231 の「4.2.1 安全メソッド」のセクション](https://tools.ietf.org/html/rfc7231#section-4.2.1) においては、「リソースの状態の変化」そのものがクライアントによって意図された要求ではないことから、引き続き「副作用」という表現が使われていますが、[RFC-7231 の「4.2.2 冪等メソッド」のセクション](https://tools.ietf.org/html/rfc7231#section-4.2.2) においては、「リソースの状態の変化」の有無に関わらず、クライアントによって意図された「作用（the intended effect）」と、クライアントによって意図されていない「副作用（side effects）」というように、より一般的な概念に近い「副作用」に変更されたことにより、「副作用」の意味論にも変更があったと解釈することができます。
（「安全と冪等」の適用範囲もより明確になりましたが、こちらは後述します。）

したがって、[RFC-7231](https://tools.ietf.org/html/rfc7231) が標準化された 2014 年 6 月以前に出版された書籍や情報を参考にされる場合には、「冪等と安全」部分の「副作用」については、適宜読み替えが必要になるかもしれませんし、それ以降の情報については、「副作用 = 状態の変化」という局所的な概念の解釈については、適宜アップデイトが必要になることでしょう。

__RFC-2616:__

```
  副作用 = 状態変化
```

__RFC-7231:__

```
副作用 ≠ 状態変化
クライアントにより意図されたもの = 主たる作用 (the effect)
クライアントにより意図されていないもの = 副作用 (side effects)
```

## 4. 安全メソッド
HTTP リクエストメソッドにおける「安全」とは、「リソースの状態を変化させない読み取り専用であること」をいいます。
それ以外の作用は副作用であり、制限もかけられず責任も追えないものとされています。
そして、「安全」を定義する目的は、クローラーや、キャッシュ機構のパフォーマンスを正常に機能させることや、クライアントに「リソースの状態の変化」を伴う作用と伴わない作用の区別を事前に知らせることができるようにするためとされています。

__安全メソッド：__
* HEAD
* GET
* OPTIONS
* TRACE

以下は、[RFC-7231 の「4.2.1 安全メソッド」のセクション](https://tools.ietf.org/html/rfc7231#section-4.2.1) の要約を箇条書きにしたものです。

* 定義済みのセマンティクスが本質的に読み取り専用の場合、リクエストメソッドは「安全」と見なされます。
* すなわち、クライアントは、安全な方法をターゲットリソースに適用した結果としてのオリジンサーバ上のいかなる状態変化も要求せず、また期待もしない。
* 同様に、安全な方法を合理的に使用しても、オリジンサーバーに何らかの危害、財産の損失、または異常な負担がかかることはありません。
* この安全なメソッドの定義は、潜在的に有害な、完全に読み取り専用ではない、または安全なメソッドを呼び出している間に副作用を引き起こすような動作が実装に含まれるのを妨げることはありません。
* しかし重要なことは、クライアントがその追加の振る舞いを要求せず、それに対して説明責任を負うことができないということです。
* たとえば、ほとんどのサーバーは、方法に関係なく、すべての応答の完了時にログファイルにアクセスするための要求情報を追加します。
* これは、ログ記憶域がいっぱいになりサーバーをクラッシュさせる場合でも安全です。
* 同様に、Web上の広告を選択することによって開始された安全な要求には、広告アカウントに請求するという副作用があります。
* この仕様で定義されている要求メソッドのうち、GET、HEAD、OPTIONS、およびTRACEメソッドは安全であると定義されています。
* 安全な方法と危険な方法を区別する目的は、自動検索プロセス（スパイダー）とキャッシュパフォーマンスの最適化（プリフェッチ）を害を及ぼす恐れなしに機能させることです。
* さらに、それはユーザーエージェントが潜在的に信頼できないコンテンツを処理するときに安全でない方法の自動使用に適切な制約を適用することを可能にします。
* ユーザエージェントは、潜在的な動作をユーザに提示するときに安全な方法と危険な方法を区別して、要求される前にユーザに危険な動作を知らせることができるべきです（SHOULD）。
* 有効なリクエストURI内のパラメータがアクションを選択する効果を持つようにリソースが構築されている場合、そのアクションがリクエストメソッドのセマンティクスと一致していることを確認するのはリソース所有者の責任です。
* たとえば、Webベースのコンテンツ編集ソフトウェアでは、 "page？do = delete"などのクエリパラメータ内のアクションを使用するのが一般的です。
* そのようなリソースの目的が危険なアクションを実行することである場合、リソース所有者は、安全な要求方法を使用してアクセスされたときにそのアクションを無効化または禁止しなければなりません。
* これを怠ると、リンク維持、事前取得、検索インデックスの構築などの目的で、自動化されたプロセスがすべてのURI参照に対してGETを実行するときに、不幸な副作用が生じます。

更に以下では「安全」の解釈について補足します。
必要の無い方はスキップしてください。

上記の「安全」の用法や定義は、HTTP のリクエストメソッドに限定した狭義のものとなります。
「安全」の用法や定義は、扱う領域によって定義の仕方が異なります。
国際基本安全規格（ISO/IEC GUIDE 51:2014）においては、

> freedom from risk which is not tolerable.
> 「許容できないリスクがないこと」

三省堂大辞林第三版においては、

> 危害または損傷・損害を受けるおそれのないこと。危険がなく安心なさま。

ブリタニカ国際大百科事典においては、

> 安全とは元来，危険や災害などによってそこなわれるおそれがない安らかな状態をいうが，生活環境が複雑化し，予測しがたいさまざまな危険性の内在している今日，安全が積極的な行動の目標として重要な意味をもちつつある。すなわち，危険な事態の予測，想定，危険要因の分析，解明と排除もしくは他の条件による補完，そして危険が生じた場合に被害を最小限にする周辺条件や事後対策の整備などによって安全が指向される。裏を返せば，安全性とは潜在する危険が発現する可能性と対応する。

とされています。
このように、広義における「安全」とは、不利益となるような作用を及ぼさないことや、予期しない作用を及ぼさないこととなるでしょう。
したがって、このような広義の「安全」を適用すると、あらゆる場面で「安全か安全でないか」を区別することが可能となります。
HTTP に限らず、システム設計の世界でも「安全」という表現を利用します。
これらのことからも、HTTP における「リソースの状態を変化させない読み取り専用であること」というような「安全」の定義は、領域固有の狭義であることが分かります。
（「安全」の詳細につきましては、また別の機会がありましたら解説します。）

したがって、HTTP リクエストメソッドの「安全」の定義は、他の領域の定義と必ずしも一致するとは限らず、HTTP リクエストメソッドの「安全」の狭義を他の領域の定義に当てはめることは適切とはいえないでしょう。
これは、前述の [副作用]() やプログラミングにおける [例外](https://qiita.com/KyojiOsada/items/4c65e3c014d27a16bb6f) などの狭義にも同様のことがいえるでしょう。

## 5. 冪等メソッド
HTTP リクエストメソッドにおける「冪等」とは、「同一のパラメーターで 1 回以上リクエストしても、リソースの状態が同じであること」をいいます。
__それ以外の作用は副作用であり、副作用も自由に実装可能とされます。__
ここで、お気づきの方もいらっしゃるでしょう。
太字の文の「副作用」の表現は、RFC-7231 に基づいた意味論によるものですが、従来の RFC-2616 の「副作用」の表現と意味論と全く違うということです。
（「副作用」の説明については、この記事の [副作用](https://qiita.com/KyojiOsada/items/9c8db9714a0c9c72823c#3-%E5%89%AF%E4%BD%9C%E7%94%A8) のセクションをご参照ください。）

そもそも、情報工学における「冪等」の定義の存在意義は、システムの堅牢性や情報の整合性を追求するためのものです。
そして、HTTP において「冪等」を定義する目的は、もしクライアントがサーバーからのリクエスト成功の応答を受信する前に通信障害が発生した場合、クライアントはリクエストをリトライしてそのリクエストの目的を達成する必要があり、サーバーはそのリトライによるリソースの不整合から保護しなければなりません。
さらに、クライアントは、同じリクエストをリトライするとリソースの整合性が破壊されるとなれば、リトライはできなくなるでしょうし、そのリトライによりリソースの整合性が保護されるのか、破壊されるのかを知らなければ無闇にリトライもできなくなるでしょう。
したがって、サーバーはこのような堅牢性を確保するとともに、クライアントにリトライ可否の区別を知らせなければなりません。
これが本来の「冪等」の目的であり、「リソースの状態の変化」に着目する理由はここにあります。
しかし、HTTP リクエストメソッドにおける「冪等」については、世界中で多くの誤解と議論を呼びました。
なぜなら、[RFC-2616](https://tools.ietf.org/html/rfc2616) では「冪等」の定義の内容に終始し、定義の目的が不明瞭だったからではないでしょうか。

以上のことから、ここでいう「リソース」の範囲を要約すると、データベース全体のことでもなく、Web サーバー全体のことでもなく、ログファイルというロールにも関係がなく、クライアント / サーバー間の界面で取り交わされた「合意形成」の内容がリソースの対象範囲になるということでしょう。
（「合意形成」の詳細にきましては、また別の機会がありましたら解説します。）

__冪等メソッド：__
* PUT
* DELETE
* 安全メソッド（HEAD, GET, OPTIONS, TRACE）

以下は、[RFC-7231 の「4.2.2 冪等メソッド」のセクション](https://tools.ietf.org/html/rfc7231#section-4.2.2) の要約を箇条書きにしたものです。

* そのメソッドを持つ複数の同一リクエストのサーバーへの意図された影響が単一のそのようなリクエストに対する影響と同じであるならば、リクエストメソッドは「冪等」と見なされます。
* この仕様で定義されている要求メソッドのうち、PUT、DELETE、および安全な要求メソッドは同じです。
* 安全の定義と同様に、冪等は、ユーザーによって要求されたものにのみ適用されます。
* サーバーは、各要求を別々に記録したり、リビジョン管理履歴を保持したり、または各べき等要求に対して他の非べき等の副作用を実装したりできます。
* クライアントがサーバーの応答を読み取ることができる前に通信障害が発生した場合に要求が自動的に繰り返される可能性があるため、べき等法は区別されます。
* たとえば、クライアントがPUT要求を送信し、応答が受信される前に基礎となる接続が閉じられた場合、クライアントは新しい接続を確立してべき等要求を再試行できます。
* たとえ元の要求が成功したとしても、応答を異ならせても、要求を繰り返すことは同じ意図された効果を持つことを知っています。

更に以下では「冪等」の解釈について補足します。
必要の無い方はスキップしてください。

「冪等」という概念は、HTTP に限らず、コンピューターの世界でも昔からある概念です。
意識的かどうかは別にして、みなさんも似たような概念で機能を実装されてきた経験があるかもしれませんし、そのような概念の機能を享受されてきたことがあるかもしれません。
例えば、ソフトウェアのインストールなども良い例です。
このように、「冪等」の概念においても、HTTP における意味論と他の領域の意味論とでは、似て非なる場合がありますので、HTTP における意味論は、領域固有の狭義であると認識しておくべきでしょう。

## 6. キャッシャブルメソッド
HTTP リクエストメソッドにおける「キャッシャブル」とは、レスポンスが将来の再利用のために保管されることを許可することをいいます。

__キャッシャブルメソッド：__
* HEAD
* GET
* (POST)

以下は、[RFC-7231 の「4.2.3 キャッシャブルメソッド」セクション](https://tools.ietf.org/html/rfc7231#section-4.2.3) の要約を箇条書きにしたものです。

* リクエストに対するレスポンスが、将来の再利用のために保管されることを許可することを示すために「キャッシュ可能」として定義する。（特定の要件については RFC-7234 を参照）
* 本定義では、GET、HEAD、POST をキャッシュ可能と定義しているが、多くのキャッシュ実装では GET と HEAD しかサポートしていない。

## 7. 安全と冪等に関する誤解
これまでのセクションを踏まえ、このセクションでは、今まで私が Web API コンサルティング業において受けてきた質問の中で「冪等と安全に関する誤解」を Q & A 方式で解いていきます。

> Q: 現在時刻やインクリメントされた ID などを取得するリクエストは、レスポンス結果が変化するから「冪等」ではないのでは？

A: 現在時刻や、インクリメント ID の取得を目的とするリクエストであれば、それは「安全かつ冪等」です。
なぜなら、現在時刻や、インクリメント ID の更新は、本リクエストによってリソースの状態を変化させたものではないからです。
また、HTTP における「冪等」は、レスポンス自体のこととは関係がありません。

> Q: GET リクエストの場合、レスポンスステータスコードが、クライアントのキャッシュ状態によって 200 Ok や 304 Not Modified に変化するから「冪等」ではないのでは？

> Q: DELETE リクエストの場合、レスポンスステータスコードが、1 度目のリクエストでは 200 Ok、2 度目のリクエストでは 404 Not Found が返却されるから「冪等」ではないのでは？

> Q: PUT リクエストの場合、レスポンスステータスコードが、1 度目のリクエストでは 201 Created、2 度目のリクエストでは 200 Ok 返却されるから「冪等」ではないのでは？

A: HTTP における「冪等」は、返却されるレスポンスステータスコードとは関係がありません。

> Q: PUT リクエストの場合、1 度目のリクエストでリソースが作成され、2 度目のリクエストでリソースが更新されるなど、そもそも 1 度目と 2 度目で内部処理が異なるため「冪等」とはいえないのでは？

> Q: DELETE リクエストの場合、1 度目のリクエストでリソースが削除され、2 度目のリクエストはリソースが見つからず何もしないなど、そもそも 1 度目と 2 度目で内部処理が異なるため「冪等」とはいえないのでは？

A: HTTP における「冪等」は、リソース内部の処理方法とは関係がなく、リソースの状態を意味します。

> Q: GET リクエストで、リソースを取得すると同時に、リクエスト毎にアクセス記録がロギングされる場合は、毎回副作用が発生するため、「冪等」ではないのでは？

> Q: 銀行口座へのリクエストは、それにより監査ログが作られるので「冪等」ではないのでは？

A: リソースの取得がリクエストの目的であれば、HTTP における「冪等」です。

> Q: GET リクエストで、リソースを取得すると同時に、未読の状態から既読に変更するときは「冪等」ではないのでは？

（この質問は「冪等と安全」を混同してしまっている例です。）
A: HTTP における「冪等」です。
おそらく「冪等」と「安全」の概念が混同されているように見受けられます。
「安全」ではないのでは？でしたら疑問として成立する気がします。
そのリクエストの目的とされるものがリソースの取得だけであり、既読への変更目的がないのであれば、既読への変更作用については合意形成外となるため「冪等」かつ「安全」となります。
逆に、そのリクエストの目的とされるものが既読への変更であれば、一般的には「非安全」かつ「冪等」となるでしょう。

> Q: PUT リクエストで、同一データを更新した場合でも、更新日時が変化する場合は「冪等」ではないため、POST や PATCH を使用すべきでは？

> Q: 例えば、そのリクエストが行われた最新時刻を記録するような場合においては、それは「冪等」ではないのでは？

A: 更新日時データが、クライアント/サーバー間の界面で交わされた合意形成の範囲外のデータである場合には、HTTP における「冪等」となります。
この場合は、複合処理となり、その処理はリクエストがトリガーになってるものの、直接的に処理を意図しているのは、クライアントのリクエストではなく、プログラム内部が意図したものであるはずです。

> Q: 「冪等」はサービス特性であってインターフェース特性ではない。

A: HTTP における「冪等」は、RFC-7231 の意味論からも、サービス特性のことではなく、インターフェイス特性のことといえるでしょう。

> Q: クライアントは、そのサービスから適切なレスポンスを得る必要があるのであって、サービスが「冪等」かどうか、ログをとるかどうかを気にしないのでは？

A: HTTP における「冪等」は、レスポンス自体のことではありません。

> Q: 「冪等」の意味するところは、メモリ内での「冪等性」ということでは？

A: HTTP における「冪等」は、メモリ内の「冪等」を意味していません。

> Q:  データベースの中も含めて状態を更新するなら「冪等」にはなり得ないのでは？

A: HTTP における「冪等」の対象となるリソースは、データベース全体の状態の事を指していません。

（これ以上の内容につきましては、また別の機会がありましたら解説します。）

## 8. PUT と PATCH メソッドについて
PUT メソッドと PATCH メソッドにおける解釈についても、ご質問やご相談をよく受けるトピックの一つです。

まず、PUT メソッドは「冪等」で、PATCH メソッドは「冪等ではない」と言い切る情報がありますが、これは正確ではありません。
PATCH メソッドの定義である、[RFC-5789](https://tools.ietf.org/html/rfc5789) では、

> PATCH is neither safe nor idempotent as defined by [RFC2616], Section 9.1.
>
> RFC-2616 の 9.1 セクションで定義されているように、PATCH は安全でも冪等でもありません。
>
> A PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame.
>
> PATCH リクエストは、冪等になるように発行することができます。これは、同様の時間枠で同じリソース上の2つのPATCH要求間の衝突による悪い結果を防ぐのにも役立ちます。

と、can be issued という表現で、PATCH リクエストは「冪等として発行することができる」とされています。
また、注意しなければならないのは、PATCH について定義されている [RFC-5789](https://tools.ietf.org/html/rfc5789) において言及されている「冪等」については、[RFC-7231](https://tools.ietf.org/html/rfc7231) の「冪等」の定義と整合性がとれているとは限らないということでしょう。
また、個人的にはあまり得策には思いませんが、PATCH メソッドは、

> 新しいリソースを作成してもよい（MAY）。

ともされています。

次に、PUT メソッドと PATCH メソッドの使い分けについてですが、こちらについてもよくご質問とご相談を受けるトピックの一つです。
PUT メソッドと PATCH メソッドの違いの一つは、「全体更新」と「部分更新」であることは間違いないでしょう。
ただし、PUT メソッドと PATCH メソッドの使い分けについて、前述のデータベースの更新日時問題のように、クライアント / サーバー間の界面において合意形成がとれていないようなリソースの更新まで話を波及させるべきではないでしょう。
例えば、

> PUT メソッドは「冪等」とされているが、同じリクエストをしてもデータベースの更新日時は都度変化してしまうため、それは「冪等」とは言えないから、データベースの更新日時が伴うようなリソースの更新には PATCH メソッドを使うべきだ

というような「冪等」に対する拡大解釈です。
これは、「冪等メソッド」のセクションでもご説明した通り、HTTP における「冪等」の解釈に誤りがある可能性があります。
「冪等」か「非冪等」かで、PUT メソッドと PATCH メソッドの使い分けを判断したい場合には、対象となるリソースが、クライアントとサーバー間の界面において合意形成がとれているものかどうかを先ず考えるべきでしょう。

そして、PUT メソッドと PATCH メソッドの使い分けについて、実はもう一つ重要な要素があります。
PUT メソッドが対象となるリソースの全体更新だとするならば、任意パラメーターの存在やリクエストパラメーターに含まれないパラメーターをどのように処理をするかというものです。
（この内容の詳細につきましては、また別の機会がありましたら解説します。）

## 9. まとめ
この記事では、HTTP における「冪等と安全に関する誤解」について投稿しました。
この「冪等」と「安全」については、今までとても多くのご質問とご相談を頂いてきましたが、特に Web API 設計においては、これらを的確に理解することはとても重要なポイントといえます。
また、私の今までの Web API 設計や、Web API コンサルティングの経験則からも、「キャッシャブル」や「副作用」についても理解された設計者が開発する Web API は、より良く進化しているように感じます。
この記事が、何かのお役に立てれば幸いです。

[^1]: https://books.google.co.jp/books?id=TkUFTtLUZN8C&pg=PA107&lpg=PA107&dq=%E6%95%B0%E5%AD%A6+%E5%89%AF%E4%BD%9C%E7%94%A8&source=bl&ots=QSzcwEW4z9&sig=ACfU3U1YRq-0eOg4EvNkGukSns5kmwb4wg&hl=ja&sa=X&ved=2ahUKEwic16OVnYvgAhWJgrwKHQaJDV8Q6AEwBnoECAAQAQ#v=onepage&q=%E6%95%B0%E5%AD%A6%20%E5%89%AF%E4%BD%9C%E7%94%A8&f=false
[^2]: https://ja.wikipedia.org/wiki/%E5%86%AA%E7%AD%89
[^3]: https://www.infoq.com/jp/news/2014/05/idempotent