Спокойный способ удалить кучу предметов

В вики-статья для REST указывается, что если вы используете http://example.com/resources DELETE, это означает, что вы удаляете всю коллекцию.

Если вы используете http://example.com/resources/7HOU57Y DELETE, это означает, что вы удаляете этот элемент.

Я делаю ВЕБ-САЙТ, обратите внимание на НЕ WEB-СЕРВИС.

У меня есть список, который имеет 1 флажок для каждого элемента в списке. Когда я выберу несколько элементов для удаления, я разрешу пользователям нажимать кнопку DELETE SELECTION. Если пользователь нажмет кнопку, откроется диалоговое окно js с просьбой подтвердить удаление. если пользователь подтвердит, все элементы будут удалены.

Итак, как я должен обслуживать удаление нескольких элементов с помощью RESTFUL?

ПРИМЕЧАНИЕ. В настоящее время для DELETE на веб-странице я использую тег FORM с POST как действие, но включаю _ метод с значением DELETE, поскольку это то, что было указано другими в SO о том, как удалить RESTful для веб-страницы.

Ответ 1

Я думаю, что ответ Рохоки пока лучший. Небольшое отклонение может заключаться в том, чтобы покончить с подтверждением javascript на той же странице, и вместо этого создать выделение и перенаправить его, отображая сообщение подтверждения на этой странице. Другими словами:

От:
http://example.com/resources/

сделать

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 (или все, что подходит для успешного удаления)

Ответ 2

Один из вариантов заключается в создании "транзакции" удаления. Таким образом, вы POST для чего-то вроде http://example.com/resources/deletes нового ресурса, состоящего из списка ресурсов, которые нужно удалить. Затем в вашем приложении вы просто выполните удаление. Когда вы делаете сообщение, вы должны вернуть местоположение вашей созданной транзакции, например, http://example.com/resources/deletes/DF4XY7. A GET на этом может вернуть статус транзакции (полный или выполняемый) и/или список ресурсов, которые необходимо удалить.

Ответ 3

Вот что сделала 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>           

Но API-интерфейс Facebook, API-интерфейс REST-интерфейса Parse Server и API REST Google Диска идут еще дальше, позволяя вам "выставлять" отдельные операции по одному запросу.

Вот пример из 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

Ответ 4

Я бы сказал DELETE http://example.com/resources/id1,id2,id3,id4 или DELETE http://example.com/resources/id1+id2+id3+id4. Поскольку "REST - это архитектура (...) [нет] протокола", чтобы процитировать эту статью в википедии, есть, я считаю, ни один способ сделать это.

Я знаю, что выше не возможно без JS с HTML, но я чувствую, что REST был:

  • Создан без учета мелких деталей, таких как транзакции. Кому нужно будет работать с более чем одним элементом? Это как-то оправдано в протоколе HTTP, поскольку оно не предназначалось для того, чтобы обслуживать через него какие-либо другие статические веб-страницы.
  • Не нужно хорошо настраивать текущие модели - даже чистый HTML.

Ответ 5

Интересно, что я думаю, что тот же метод применяется в отношении PATCHing нескольких объектов и требует размышления о том, что мы имеем в виду с нашими URL-адресами, параметрами и методом REST.

  • вернуть все элементы 'foo':

    [GET] api/foo

  • вернуть элементы 'foo' с фильтрацией для определенных идентификаторов:

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

В каком смысле URL-адрес и фильтр определяют "какие элементы мы имеем в виду?", а метод REST (в данном случае "GET" ) говорит "что делать с этими элементами?"

  • Следовательно, PATCH несколько записей, чтобы отметить их как прочитанные

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

.. с данными foo [read] = 1

  • Наконец, чтобы удалить несколько записей, эта конечная точка наиболее логична:

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

Пожалуйста, поймите, я не верю, что есть какие-то "правила" по этому поводу - для меня это просто "имеет смысл"

Ответ 6

Как говорится в ответе " Достойный дабблер" и "ответ rojocas", наиболее каноничным является использование виртуальных ресурсов для удаления выбранных ресурсов, но я считаю, что это неправильно с точки зрения REST, поскольку выполняется DELETE http://example.com/resources/selections/DF4XY7 должен удалить сам ресурс выбора, а не выбранные ресурсы.

Принимая ответ Maciej Piechotka или ответ fezfox, у меня есть только одно возражение: существует более канонический способ передачи массива идентификаторов, и используется оператор массива:

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

Таким образом, вы атакуете конечную точку "Удалить коллекцию", но правильно фильтруете удаление с помощью строки запроса.

Ответ 7

Поскольку нет "правильного" способа сделать это, то, что я делал в прошлом, это:

отправьте DELETE в http://example.com/something с XML-или json-кодированными данными в теле.

когда вы получаете запрос, установите для параметра DELETE значение true, затем прочитайте тело для тех, которые будут удалены.