REST API の HTTP 動詞設計の現実¶
原文¶
究極的には GET/POST/PUT/DELETE そして HEAD/OPTIONS/PATCH なんかも含めての REST なんですが、HEAD/OPTIONS あまり要件が無いのと、POST/PUT/PATCH の区別があやふやになりがちなのと、HTTP Proxy のせいで POST 以外の更新系が送れなくて(x-http-method-override: DELETE) 全部 POST にしてしまった等の、悪い過去もあり、しまいには最近の流行りなのか全部 POST にするヤンチャ系も出てきて(もはやそれは REST ではないが)、崇高な REST の設計思想は崩れ始めている。
要約¶
RESTはGET/POST/PUT/DELETE/PATCH等の動詞を使い分けることが原則だが、現実にはProxy制約・POST/PUT/PATCHの区別の曖昧さ・「全部POST」ヤンチャ設計等により崩れがち。mattnがRESTの設計思想の理想と現実のギャップを指摘。
解説¶
REST における HTTP メソッドの本来の役割¶
| メソッド | 用途 | 冪等性 | 安全性 |
|---|---|---|---|
| GET | リソースの取得 | ○ | ○ |
| POST | リソースの作成 / アクション実行 | ✗ | ✗ |
| PUT | リソースの完全置換 | ○ | ✗ |
| PATCH | リソースの部分更新 | △ | ✗ |
| DELETE | リソースの削除 | ○ | ✗ |
| HEAD | ヘッダーのみ取得(GETの軽量版) | ○ | ○ |
| OPTIONS | 対応メソッドの確認(CORS等) | ○ | ○ |
現実に生じる問題¶
1. POST / PUT / PATCH の区別の曖昧さ¶
- PUT: リソース全体を送信して置換(一部省略=nullとして扱う)
- PATCH: 変更したいフィールドだけ送信して部分更新
- 実装が複雑になるため、チームによっては「PUTですべて」「PATCHは使わない」等の判断をすることがある
2. HTTP Proxy の制約¶
- 古いProxyはPOST以外の更新系メソッドを通さないものがあった
- 対策として
x-http-method-override: DELETEヘッダーをPOSTリクエストに付けて実際のメソッドを示す回避策が生まれた
3. 「全部POST」設計(RPCスタイル)¶
- GraphQL / gRPC / tRPC はこのRPCスタイルの現代的な形
- 「RESTではない」が、スキーマ定義・型安全性・ツールの充実度で実用的な選択肢になっている
現代的な選択肢¶
| アプローチ | 特徴 | 向いている場面 |
|---|---|---|
| REST(厳密) | HTTPメソッドを正しく使う | 公開API、標準的なCRUD |
| REST(緩い) | GET/POST中心 | チーム内API、レガシー互換 |
| GraphQL | POST一択、クエリ言語 | フロントが多様なデータを必要とする場合 |
| gRPC | HTTP/2 + Protocol Buffers | マイクロサービス間通信 |
→ 関連: オフセット vs カーソルページネーション、APIゲートウェイ