RESTはきれいだが、設計に苦悩することがあるのも確か!
正直、今回の話は正解がわかりません。
どれが正解? - エンティティの部分更新
- 例えばユーザ名のみ変更するAPIは?
PUT https://example.com/user/1/
{ "name": "jabara" }
※実装たいへん!
PATCH https://example.com/user/1/
{ "name": "jabara" }
※実装たいへん!
PUT https://example.com/user/1/name
"jabara"
どれが正解? - エンティティのリストの同時更新
- 多数のユーザの情報を同時に更新
PUT https://example.com/user/1
{ ... }
PUT https://example.com/user/2
{ ... }
PUT https://example.com/user/3
{ ... }
※明らかに非効率!
※トランザクションが分離してしまう!
PUT https://example.com/user/1,2,3
{
"user": [
"id": 1,
"name": ...
],
...
}
※メソッドどれにするか迷う
※URL中のID値とボディがずれたらどうする?
POST https://example.com/user/
{
"user": [
"id": 1,
"name": ...
],
...
}
※メソッドどれにするか迷う
※UPSERTな動きになるだろう
※この辺が落としどころな気がする
どれが正解? - 特殊な操作
- 既読処理
PUT https://example.com/blog/1/article/1
{ "read": true }
PUT https://example.com/blog/1/article/1/read
※ボディはなし?だとすると未読に戻すには?
RESTの弱点
- 何を「リソース」とみなすか、という問題
- 「既読」をリソースとするならば、未読にする操作は以下のように表現できる
DELETE https://example.com/blog/1/article/1/read
・・・ちょっと非直感的。この表現力の低さがRESTの弱点と言える。
もう1つの弱点 - 複数リソースや複数回の操作の扱い
- 複数のリソースをトランザクショナルに更新したい
- 複数回の操作をトランザクショナルに実施したい
- RESTではこれを素直に表現できない
もう1つの弱点 - 複数リソースや複数回の操作の扱い
- RESTはシンプルで分かりやすいが、業務的に要件を満たすには不足することがある
- 非汎用的な、特定の画面に特化した仕様にせざるを得ない
ここは割り切り!
最後に
- RESTはきれいだがときには現実との折り合いを付ける必要がある
- そうだ、GraphQLにしよう!