たくさんのアイテムを削除するための落ち着いた方法


97

ではRESTのためのwikiの記事 、あなたが使用している場合ていることを示しているhttp://example.com/resources手段あなたがコレクション全体を削除していることを、DELETE。

http://example.com/resources/7HOU57Y DELETE を使用する場合は、その要素を削除することを意味します。

私はウェブサイトをやっています、ウェブサービスではないことに注意してください。

リストの各アイテムに1つのチェックボックスがあるリストがあります。削除するアイテムを複数選択したら、ユーザーが[DELETE SELECTION]というボタンを押すことを許可します。ユーザーがボタンを押すと、削除の確認を求めるjsダイアログボックスがポップアップします。ユーザーが確認すると、すべてのアイテムが削除されます。

では、どのようにすれば、複数のアイテムをRESTLULな方法で削除できるでしょうか?

NOTEは、現在のWebページでのDELETEのために、私は何をやっていることは、私はアクションとしてPOSTでFORMタグを使用しますが、以来、DELETE値との_methodなどがあり、これは、WebページのためのRESTfulな削除を行う方法にSOで他の人によって示されたものです


1
これらの削除がアトミックに実行されることは重要ですか?31番目を削除できない場合、最初の30項目の削除を元に戻してもよろしいですか?
Darrel Miller、

@darrelmillerいい質問です。私は思っ削除がアトミックに実行されている場合、それはあまり効率的になります。したがって、DELETE FROM tablename WHERE ID IN({list of ids})に傾いています。誰かが私にこれが良いアイデアであるのか、それとも私を正してくれるのかを指摘できるなら。よろしくお願いします。また、21日目が削除された場合、最初の20アイテムの削除を元に戻す必要はありません。繰り返しますが、リバースする必要がある場合とリバースする必要がない場合のアプローチの違いを誰かに教えてもらえれば
幸いです

1
注:「IN」句には制限がある場合があります。たとえば、Oracleでは最大1000個のIDを指定できます。
rob

GoogleのAPI設計ガイドは、REST APIでカスタム(バッチ)オペレーションを作成するためのソリューションを提供しています。私の回答はこちらをご覧ください:stackoverflow.com/a/53264372/2477619
B12Toaster

回答:


53

ロホカの答えは今のところ最高だと思います。わずかなバリエーションとして、同じページでJavaScriptの確認を行わずに、選択を作成してリダイレクトし、そのページに確認メッセージを表示する場合があります。言い換えると:

差出人:http :
//example.com/resources/

する

IDを選択してPOSTする:http :
//example.com/resources/selections

成功すると、次のように応答します。

HTTP / 1.1 201が作成され、Locationヘッダーが
http://example.com/resources/selections/DF4XY7

このページに(JavaScript)確認ボックスが表示されます。確認すると、次の要求が行われます。

削除http://example.com/resources/selections/DF4XY7

成功した場合、HTTP / 1.1 200 Ok(または正常な削除に適切なもの)で応答する必要があります。


リダイレクトが必要ないため、このアイデアが気に入っています。AJAXを組み込むと、ページを離れることなくこれをすべて実行できます。
rojoca

このDELETE example.com/resources/selections/DF4XY7の後、example.com / resourcesにリダイレクトされますか?
キムスタック2010年

7
@fireeyeboyこの2段階のアプローチは、複数削除を実行する方法として一般的に提案されているようですが、なぜですか?単純なDELETEリクエストをURIのように送信し、リクエストhttp://example.com/resources/selections/のペイロード(本文)で、削除するアイテムのデータを送信しないのはなぜですか。私の知る限り、これを妨げるものは何もありませんが、私は常に「RESTfullではありません」と出会います。
thecoshman 2013年

6
削除することができ、潜在的に体がHTTPインフラストラクチャによって無視されています:stackoverflow.com/questions/299628/...
ルークPuplett

DELETEには本体を
含める

54

1つのオプションは、削除「トランザクション」を作成することです。したがって、削除するリソースのリストで構成される新しいリソースのPOSTようなものに移動http://example.com/resources/deletesします。次に、アプリケーションで削除を実行します。投稿を行うとき、作成したトランザクションの場所を返す必要がありますhttp://example.com/resources/deletes/DF4XY7。これのA GETは、トランザクションのステータス(完了または進行中)および/または削除されるリソースのリストを返す可能性があります。


2
データベースとは何の関係もありません。トランザクションとは、実行する操作のリストを意味します。この場合、それは削除のリストです。行うことは、アプリケーションのリソースとして(削除の)新しいリストを作成することです。Webアプリケーションは、必要に応じてそのリストを処理できます。そのリソースにはURIがあります(例:example.com/resources/deletes/DF4XY7)。これは、そのURIへのGETを介して削除のステータスを確認できることを意味します。これは、削除を行ったときにAmazon S3またはその他のCDNからイメージを削除する必要があり、その操作が完了するまでに時間がかかる場合に便利です。
rojoca 2010年

2
+1これは素晴らしい解決策です。@rojocaは、各リソースにDELETEを送信する代わりに、リソースのリストを削除することだけをタスクとする新しいタイプのリソースのインスタンスを作成することを提案します。たとえば、ユーザーリソースのコレクションがあり、コレクションからユーザーBob、Dave、Amyを削除したい場合は、作成パラメーターとしてBob、Dave、AmyをPOSTする新しい削除リソースを作成します。Deletionリソースが作成され、UsersコレクションからBob、Dave、Amyを削除する非同期プロセスを表します。
Mike Tunnicliffe 2010年

1
ごめんなさい。私はまだいくつかの問題を理解するのに若干の困難を抱えています。DF4XY7。一体どうやってこの文字列を生成しますか?この削除リソース。データベースにデータを挿入する必要がありますか?質問を繰り返した場合は、お詫び申し上げます。私にはなじみがありません。
キムスタック

1
私はDF4XY7が生成された一意のIDであると想定しています。おそらく、example.com / resources / deletes / 7のように、DBに保存されたときに生成されたIDを使用する方が自然です。私の考えは、削除モデルを作成してデータベースに保存することです。他のレコードを削除する非同期プロセスで、削除モデルを完了ステータスと関連するエラーで更新できます。
Mike Tunnicliffe 2010年

2
@rojocaええ、問題はHTTPが非常に「DELETEは単一のリソースを削除することです」ということだと思います。何をするにしても、複数の削除を取得するのは少しハックです。クライアントに「ジョブ」を返すことはできますが、このタスクは処理中です(時間がかかる場合があります)が、このURIを使用して進行状況を確認できます。私は仕様を読み、DELETEが他のリクエストと同じようにボディを持つことができると考えました。
thecoshman 2013

33

AmazonがS3 REST APIを使って行ったことを次に示します。

個別の削除リクエスト:

DELETE /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Content-Length: length
Authorization: authorization string (see Authenticating Requests (AWS Signature Version 4))

マルチオブジェクト削除リクエスト:

POST /?delete HTTP/1.1
Host: bucketname.s3.amazonaws.com
Authorization: authorization string
Content-Length: Size
Content-MD5: MD5

<?xml version="1.0" encoding="UTF-8"?>
<Delete>
    <Quiet>true</Quiet>
    <Object>
         <Key>Key</Key>
         <VersionId>VersionId</VersionId>
    </Object>
    <Object>
         <Key>Key</Key>
    </Object>
    ...
</Delete>           

しかし、Facebook Graph APIParse Server REST APIGoogle Drive REST APIは、1つのリクエストで個々の操作を「バッチ」できるようにすることで、さらに進化します。

以下は、Parse Serverの例です。

個別の削除リクエスト:

curl -X DELETE \
  -H "X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
  https://api.parse.com/1/classes/GameScore/Ed1nuqPvcm

バッチリクエスト:

curl -X POST \
  -H "X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
        "requests": [
          {
            "method": "POST",
            "path": "/1/classes/GameScore",
            "body": {
              "score": 1337,
              "playerName": "Sean Plott"
            }
          },
          {
            "method": "POST",
            "path": "/1/classes/GameScore",
            "body": {
              "score": 1338,
              "playerName": "ZeroCool"
            }
          }
        ]
      }' \
  https://api.parse.com/1/batch

13

DELETE http://example.com/resources/id1,id2,id3,id4またはDELETE http://example.com/resources/id1+id2+id3+id4と言います。「RESTはアーキテクチャー(...)[ではない]プロトコル」なので、このWikipediaの記事を引用すると、これを行うための単一の方法はないと思います。

JSとHTMLがなければ上記は不可能であることは承知していますが、RESTが次のようなものだったと感じています。

  • トランザクションのような細かい詳細を考慮することなく作成されました。1つ以上のアイテムを操作する必要があるのは誰ですか?HTTPプロトコルでは、静的Webページ以外のサービスを提供することを意図していないため、これはどういうわけか正当化されます。
  • 純粋なHTMLであっても、現在のモデルにうまく合わせる必要はありません。

thx-コレクション全体を削除したい場合はどうすればよいですか-次にIDを省略しますか?
BKSpurgeon 2017年

「RESTは...トランザクションのような細かいことを考えずに作成されたような気がします」—それは本当だとは思いません。私が正しく理解していれば、RESTではトランザクションはメソッドではなくリソースによって表されます。このブログ投稿のこのコメントで最高潮になるいくつかの良い議論があります。
ポールD.ウェイト2017年

10

興味深いことに、複数のエンティティのPATCHに関しても同じ方法が適用されると思います。URL、パラメーター、およびRESTメソッドの意味を考える必要があります。

  1. すべての「foo」要素を返します。

    [GET] api/foo

  2. 特定のIDをフィルタリングして「foo」要素を返します。

    [GET] api/foo?ids=3,5,9

ここで、URLとフィルターが「処理する要素は何か」を決定し、RESTメソッド(この場合は「GET」)は「これらの要素をどうするか」を意味します。

  1. したがって、複数のレコードをパッチして、それらを既読としてマークします

    [PATCH] api/foo?ids=3,5,9

..データfoo [read] = 1を使用

  1. 最後に、複数のレコードを削除するには、このエンドポイントが最も論理的です。

    [DELETE] api/foo?ids=3,5,9

これには「ルール」があるとは思わないことを理解してください-私にとってそれは単に「理にかなっている」


実際にPATCHに関してエンティティのリストをエンティティ自体として考える場合(タイプが配列であっても)部分的な更新を意味するため、部分的なエンティティの部分的な配列(更新するIDのみ)を送信すると、はクエリ文字列を省略できるため、複数のエンティティを表すURLがありません。
SzabolcsPáll15年

2

まともな生噛じりの解答rojocas答えは言う、最も標準的なリソースの選択を削除するには、仮想リソースを使用しているが、私はAを実行するためにそれは、RESTの観点から間違っていると思いますDELETE http://example.com/resources/selections/DF4XY7の選択リソース自体ではなく、選択したリソースを削除する必要があります。

Maciej Piechotka anwserまたはfezfox answerをとると、私は異論があります:IDの配列を渡すより標準的な方法があり、配列演算子を使用しています:

DELETE /api/resources?ids[]=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d&ids[]=7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b

このようにして、コレクションの削除エンドポイントを攻撃していますが、クエリ文字列を使用して削除を適切にフィルタリングしています。


-1

これを行う「適切な」方法はないので、私が過去に行ったことは次のとおりです。

本文にxmlまたはjsonでエンコードされたデータを含むDELETEをhttp://example.com/somethingに送信します。

リクエストを受け取ったら、DELETEを確認します。trueの場合は、削除するものの本文を読み取ります。


これは私にとって意味のあるアプローチです。1回のリクエストでデータを送信するだけですが、私は常に「RESTfullではありません」と出会います。これが実行可能な「RESTfull」の方法であることを示唆する情報源はありますか?
thecoshman 2013年

10
このアプローチの問題は、DELETE操作では本体が予期されないため、インターネット上の中間ルーターの一部がユーザーの制御や知識なしに削除する可能性があることです。したがって、DELETEに本体を使用することは安全ではありません。
Alex White

:アレックスのコメントを参考stackoverflow.com/questions/299628/...
ルークPuplett

1
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.tools.ietf.org/html/rfc7231#section-4.3.5
cottton

-1

同じ状況で複数のアイテムを削除しました。これは私がやったことです。私はDELETE操作を使用し、削除されるアイテムのIDはHTTPヘッダーの一部でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.