66

データ サービスの削除の取り消しまたは遅延/バッチ削除をサポートすることは、かなり一般的な要件です。私が疑問に思っているのは、これを RESTful な方法で実装する方法です。私はいくつかの異なるオプションの間で引き裂かれています (どれも私にとってひどく魅力的ではないようです)。これらのさまざまなオプションに共通するのは、特定のリソース タイプに対して削除済みとしてマークされたすべてのリソースを返す API の必要性だと思います。

私が考えたいくつかのオプションと、それらの長所と短所のいくつかを次に示します。

リソースを削除済みとしてマークするオプション:

  • HTTP DELETE を使用して、リソースを削除済みとしてマークします。
  • HTTP PUT/POST を使用して、削除済みフラグを更新します。これは、本質的に削除を HTTP DELETE メソッドから離れて他の HTTP メソッドにマッピングするため、適切ではありません。

削除対象としてマークされたリソースを GET するときのオプション:

  • 削除済みとしてマークされたリソースの HTTP ステータス 404 を返します。クリーンで透過的ですが、実際に削除されたリソースと削除済みとしてマークされたばかりのリソースの違いはどうすればわかりますか。
  • HTTP ステータス 410 を返します。違いを見分ける方法を提供しますが、410 は技術的には「永続的であると見なされることが期待されます。リンク編集機能を持つクライアントは、ユーザーの承認後に Request-URI への参照を削除する必要があります」と述べています。ここでの「期待される」および「すべき」という言葉には、十分な調整の余地があるかもしれません。クライアントで 410 がどの程度サポートされているか、または理解されているかは不明です。
  • HTTP ステータス 200 を返し、リソースが削除されたことを示すフラグ フィールドを含めます。そもそもそれを削除するという考えは、実際には表示されないようにしたかったからです。これにより、削除されたリソースを除外する責任がクライアントに押し付けられます。

この削除されたリソースを含む応答のオプション:

  • 削除済みとしてマークされたリソースを省略します。クリーン&シンプル。しかし、削除されたリソースについて実際に知りたい場合はどうでしょう。
  • それらが削除されたことを示すフィールドとともにそれらを含めます。これにより、削除されたリソースを除外する責任がクライアントに押し付けられます。アクティブなリソースまたは削除されたリソースのみをページングしたい場合、ページネーションが難しくなります。

削除対象としてマークされたリソースを更新するときのオプション:

  • HTTP ステータス 404 を使用します。リソースがなくなりましたよね? しかし、削除済みとしてマークされたリソースと実際に削除されたリソースの違いをどのように見分けることができますか。404 応答の HTTP 本文はここで明確にすることができますが、クライアントは本文を解析/解釈して明確にする必要があります。たぶん、応答ヘッダーがここで役立つでしょうか? どれ?カスタムヘッダー?
  • リソースを最初に復元する方法についてのメッセージとともに HTTP ステータス 409 を使用します。

削除対象としてマークされたリソースの削除を取り消すオプション:

  • リソースの更新操作に HTTP PUT/POST を使用し、再度アクティブとしてマークします。これは、「見つかりません」(404) であるリソースに PUT/POST を実行しないため、リソースの GET 操作に対して HTTP 404 を返さない場合にのみ機能します。
  • リソースの作成操作には HTTP PUT/POST を使用します。ここでの問題は、どのデータが優先されるかということです。作成操作で送信されたデータ? それとも復元されたデータですか?それを返す他のクエリからそれを除外します。次に、リソース識別子が削除済みとしてマークされたリソースを指している場合、リソースを作成する HTTP PUT/POST を削除取り消しとして扱います。
  • 削除対象としてマークされたリソースの削除を取り消す専用の別の REST パス。

これは決して網羅的なリストではありません。頭の中で飛び回っているいくつかのオプションを列挙したかっただけです。

これを行う方法に対する答えは、いつものように「場合によります」であることを私は知っています。私が興味を持っているのは、決定を下すためにどのような資格/要件を使用するかということです. これが実装されているのをどのように見ましたか、または自分で実装しましたか?

4

6 に答える 6

11

本によると: RFC 2616-9.7 :

  The DELETE method requests that the origin server delete the resource 
  identified by the Request-URI. This method MAY be overridden by human 
  intervention (or other means) on the origin server. The client cannot
  be guaranteed that the operation has been carried out, even if the 
  status code returned from the origin server indicates that the action
  has  been completed successfully. However, the server SHOULD NOT 
  indicate success unless, at the time the response is given, if it intends
  to delete the resource or move it to an inaccessible location.

リソースを DELETE すると、サーバーはそのリソースに削除のマークを付ける必要があります。リソースを実際に削除する必要はありません。操作が実行されたことを保証することはできません。それでも、サーバーは削除されていないのに削除されたと言うべきではありません。

  A successful response SHOULD be 200 (OK) if the response includes an entity
  describing the status, 202 (Accepted) if the action has not yet been enacted,
  or 204 (No Content) if the action has been enacted but the response does not
  include an entity.

操作が遅れている場合は、アクションの結果を説明する 202 とエンティティ本体を送信します。(サーバーによるリソースの延期された削除を表すポーリング可能な「タスク」を考えてみてください。理論的には、リソースをその状態のまま永久に残すことができます。)それがしなければならないことは、クライアントが元の形式でリソースを再度取得するのを防ぐことだけです。応答コードに 410 を使用し、「タスク」が終了するか、サーバーがリソースを削除すると、404 を返します。

ただし、問題のリソースに対して DELETE のセマンティクスが意味をなさない場合、探しているのはおそらく削除ではなく、リソースの状態を変更するがアクセス可能な状態を維持する追加の状態遷移でしょうか? その場合は、PUT/PATCH を使用してリソースを更新し、完了します。

于 2011-12-24T02:10:55.850 に答える
5

これを解決する最も RESTful な方法は、HTTP PUT を使用してリソースに削除のマークを付け (および削除を取り消す)、次に HTTP DELETE を使用してリソースを完全に削除することだと思います。削除対象としてマークされたリソースのリストを取得するには、HTTP GET リクエストでパラメーターを使用します。?state=markedForDeletion. パラメータなしで削除対象としてマークされたリソースをリクエストした場合、「404 Not Found」ステータスを返す必要があると思います。

于 2011-12-24T00:23:55.837 に答える