114

HTTP 1.1仕様では、DELETE要求でメッセージ本文を許可しているように見えますが、定義されたセマンティクスがないため、サーバーはそれを無視する必要があることを示しているようです。

4.3メッセージ本文

サーバーは、要求に応じてメッセージ本文を読み取って転送する必要があります。リクエストメソッドにエンティティ本体に定義されたセマンティクスが含まれていない場合、リクエストを処理するときにメッセージ本文を無視する必要があります。

SO以降のこのトピックに関するいくつかの関連するディスカッションをすでに確認しました。

ほとんどの議論は、DELETEでメッセージ本文を提供することが許可される可能性があることに同意しているようですが、一般的には推奨されていません。

さらに、さまざまなHTTPクライアントライブラリの傾向に気づきました。これらのライブラリでは、DELETEのリクエスト本文をサポートするために、ますます多くの拡張機能がログに記録されているようです。ほとんどの図書館は義務を負っているようですが、初期の抵抗が少しあることもあります。

私のユースケースでは、DELETEに必要なメタデータを追加する必要があります(たとえば、削除の「理由」と、削除に必要な他のメタデータ)。私は次のオプションを検討しましたが、どれも完全に適切であり、HTTP仕様やRESTのベストプラクティスに沿っているようには見えません。

  • メッセージ本文-仕様は、DELETEのメッセージ本文にセマンティック値がないことを示しています。HTTPクライアントでは完全にはサポートされていません。標準的な慣行ではありません
  • カスタムHTTPヘッダー-カスタムヘッダーを要求することは、一般的に標準的な慣行に反します。それらを使用することは私のAPIの他の部分と矛盾しており、いずれもカスタムヘッダーを必要としません。さらに、悪いカスタムヘッダー値を示すために利用できる良いHTTP応答がありません(おそらく完全に別の質問)
  • 標準のHTTPヘッダー-適切な標準ヘッダーはありません
  • クエリパラメータ-クエリパラメータを追加すると、削除されるRequest-URIが実際に変更されます。標準的な慣行に対して
  • POSTメソッド-(例POST /resourceToDelete { deletemetadata })POSTは削除のセマンティックオプションではありません。POSTは、実際には必要な反対のアクションを表します(つまり、POSTはリソースの従属を作成しますが、リソースを削除する必要があります)
  • 複数のメソッド-DELETEリクエストを2つの操作(たとえば、PUTメタデータの削除、次にDELETE)に分割すると、アトミック操作が2つに分割され、一貫性のない状態が残る可能性があります。削除理由(およびその他の関連メタデータ)は、リソース表現自体の一部ではありません。

私の最初の好みは、おそらくカスタムHTTPヘッダーの次にメッセージ本文を使用することでしょう。ただし、示されているように、これらのアプローチにはいくつかの欠点があります。

DELETEリクエストにそのような必要なメタデータを含めるためのREST/HTTP標準に沿った推奨事項またはベストプラクティスはありますか?私が検討していない他の選択肢はありますか?

4

4 に答える 4

52

DELETE要求にメッセージ本文を使用しないといういくつかの推奨事項にもかかわらず、このアプローチは特定のユースケースで適切な場合があります。これは、質問/回答に記載されている他のオプションを評価し、サービスの利用者と協力した後に使用することになったアプローチです。

メッセージ本文の使用は理想的ではありませんが、他のオプションも完全に適合していませんでした。リクエスト本文のDELETEを使用すると、DELETE操作に付随する必要のある追加のデータ/メタデータに関するセマンティクスを簡単かつ明確に追加できます。

私はまだ他の考えや議論を受け入れるつもりですが、この質問のループを閉じたいと思いました。このトピックに関する皆さんの考えと議論に感謝します!

于 2013-03-18T16:36:19.890 に答える
12

あなたが望んでいるように見えるのは2つのもののうちの1つであり、どちらも純粋ではありませんDELETE

  1. 2つの操作があります。1つPUTは削除理由の後に、もう1つDELETEはリソースです。削除されると、リソースのコンテンツには誰もアクセスできなくなります。'reason'には、削除されたリソースへのハイパーリンクを含めることはできません。または、
  2. メソッドを使用して、リソースをからstate=activeに変更しようとしています。state = deletedのリソースは、メインAPIによって無視されますが、管理者またはデータベースアクセス権を持つユーザーが引き続き読み取ることができる場合があります。これは許可されています-リソースのバッキングデータを消去する必要はありません。そのURIで公開されているリソースを削除するだけです。state=deletedDELETEDELETE

リクエストでメッセージ本文を必要とする操作は、DELETE最も一般的にはPOST、メッセージ本文で必要なすべてのタスクを実行するための操作と、に分類できますDELETE。HTTPのセマンティクスを破る理由はわかりません。

于 2013-01-15T09:10:13.347 に答える
10

あなたの状況を考えると、私は次のいずれかのアプローチを取ります。

  • PUTまたはPATCHを送信する:削除理由が必要な性質上、削除操作は仮想であると推測しています。したがって、それ自体はDELETE操作ではありませんが、PUT/PATCH操作を介してレコードを更新することは有効なアプローチであると思います。
  • クエリパラメータを使用します。リソースURIは変更されていません。実際、これも有効なアプローチだと思います。リンクした質問は、クエリパラメータが欠落している場合に削除を許可しないことについて話していました。あなたの場合、理由がクエリ文字列で指定されていない場合、デフォルトの理由があります。リソースは引き続きですresource/:id。理由ごとにリソースのリンクヘッダーを使用して検出可能にすることができます(理由relを識別するためにそれぞれにタグを付けます)。
  • 理由ごとに個別のエンドポイントを使用する:のようなURLを使用しresource/:id/canceledます。これは実際にはRequest-URIを変更し、RESTfulではありません。繰り返しますが、リンクヘッダーはこれを発見可能にすることができます。

RESTは法や教義ではないことを忘れないでください。それをガイダンスとしてもっと考えてください。したがって、問題のあるドメインのガイダンスに従わないことが理にかなっている場合は、従わないでください。APIコンシューマーに差異が通知されていることを確認してください。

于 2013-01-15T05:37:24.603 に答える
0

URI階層自体の一部として必要なメタデータを含めることをお勧めします。例(ナイーブ):

開始日と終了日を本文またはクエリパラメータとして渡すのではなく、日付範囲に基づいてエントリを削除する必要がある場合は、必要な情報をURIの一部として渡すようにURIを構成します。

例えば

DELETE /entries/range/01012012/31122012-2012年1月1日から2012年12月31日までのすべてのエントリを削除します

お役に立てれば。

于 2013-01-15T07:07:51.987 に答える