1. ホーム
  2. json

[解決済み] REST。1つのリクエストで複数のリソースを更新する - それは標準なのか、それとも避けるべきことなのか?

2023-01-27 23:48:40

質問

シンプルなREST APIです。

  • GET: items/{id} - 指定された ID のアイテムの説明を返します。
  • PUT: items/{id} - 指定された ID のアイテムを更新または作成します。
  • DELETE: items/{id} - 指定されたidのアイテムを削除します。

さて、問題のAPI-extensionです。

  • GET: items?filter - フィルタに一致するすべてのアイテムIDを返します。
  • PUT: items - JSON ペイロードによって記述されるように、アイテムのセットを更新または作成します。
  • [[ DELETE: items - JSONペイロードによって記述されたアイテムのリストを削除する ]] <- 正しくない

私は今、PUT/DELETE items/{id}で簡単にアクセスできるDELETEとPUT操作のリサイクル機能に興味を抱いています。

質問です。このようなAPIを提供することは一般的なことでしょうか?

代替案です。Single Connection Multiple Requestsの時代には、複数のリクエストを発行することは安価で、変更が成功するか失敗するかのどちらかなので、よりアトミックに動作するでしょうが、NOSQLデータベースの時代には、何らかの理由で内部サーバーなどでリクエスト処理が終了しても、リストの変更はすでに起こっているかもしれません。

[UPDATE]

検討の結果 ホワイトハウスウェブスタンダード ウィキペディア REST の例 を利用することで、以下のような例題APIが意図されるようになりました。

シンプルなREST APIです。

  • GET: items/{id} - 指定された ID のアイテムの説明を返します。
  • PUT: items/{id} - 指定された ID のアイテムを更新または作成します。
  • DELETE: items/{id} - 指定されたidのアイテムを削除します。

トップリソースのAPIです。

  • GET: items?filter - フィルタに一致するすべてのアイテムIDを返します。
  • POST: items - JSON ペイロードによって記述されるように、アイテムのセットを更新または作成します。

/itemsに対するPUTとDELETEはサポートされておらず、禁止されています。

POSTを使用すると、置き換えずに追加しながら、包含するリソースに新しいアイテムを作成するものとして、トリックを行うようです。

HTTPセマンティクス POST 読み取ります。

追加操作でデータベースを拡張する

で引用されるような同等の表現を返すために、PUTメソッドが完全なコレクションを置き換える必要がある場合。 HTTPセマンティクス PUT :

与えられた表現のPUTが成功した場合、その後に同じターゲットリソース上でGETを行うと、同等の表現が200 (OK)レスポンスで返されることが示唆されます。

[UPDATE2]

複数オブジェクトの更新の面でさらに一貫性があると思われる代替手段は、PATCHメソッドと思われます。PUTとPATCHの違いについては ドラフト RFC 5789 というように記載されています。

PUTリクエストとPATCHリクエストの違いは、Request-URIによって識別されるリソースを変更するために、サーバーが同封のエンティティを処理する方法に反映されます。 PUTリクエストでは、同封のエンティティはオリジンサーバーに保存されたリソースの修正バージョンとみなされ、クライアントは保存されたバージョンを置き換えるよう要求しています。 しかし、PATCHでは、同封の実体は、現在オリジンサーバーに存在するリソースが新しいバージョンを生成するためにどのように修正されるべきかを記述する命令のセットを含んでいます。 PATCHメソッドはRequest-URIによって識別されるリソースに影響を与え、それはまた、他のリソースに副作用を持ってもよい(MAY)。

POSTと比較すると、PATCHはUPDATEが可能であり、POSTは修正の機会なしに何かを追加することしかできません。

つまり、POSTは間違いであり、私たちが提案するAPIを変更する必要があります。

シンプルなREST APIです。

  • GET: items/{id} - 指定された ID のアイテムの説明を返します。
  • PUT: items/{id} - 指定された ID のアイテムを更新または作成します。
  • DELETE: items/{id} - 指定されたidのアイテムを削除します。

トップリソースのAPIです。

  • GET: items?filter - フィルタに一致するすべてのアイテムIDを返します。
  • POST: items - JSON ペイロードによって記述されるように、1つまたは複数のアイテムを作成します。
  • PATCH: items - JSON ペイロードで記述された 1 つまたは複数のアイテムを作成または更新します。

どのように解決するのですか?

コレクションをPATCHすることができます、例えば。

PATCH /items
[ { id: 1, name: 'foo' }, { id: 2, name: 'bar' } ]

技術的には、PATCHはURLのレコードを識別します(つまり、PATCH /items/1 でレコードを識別し、リクエストボディでは識別しませんが、これは良い実用的なソリューションのように思えます。

単一の呼び出しで削除、作成、および更新をサポートするために、それは標準的なREST規約によって実際にサポートされていません。1つの可能性は、一緒に呼び出しを組み立てることができる特別なquot;batch"サービスです。

POST /batch
[
  { method: 'POST', path: '/items', body: { title: 'foo' } },
  { method: 'DELETE', path: '/items/bar' }
]

は、埋め込まれた各リクエストのステータスコードでレスポンスを返す。

[ 200, 403 ]

あまり標準的ではありませんが、私がやってみたところうまくいきました。