Qual é a maneira REST completa de excluir vários itens?
Meu caso de uso é que tenho uma coleção de backbone em que preciso ser capaz de excluir vários itens de uma vez. As opções parecem ser:
- Envie uma solicitação DELETE para cada registro (o que parece uma má ideia se houver potencialmente dezenas de itens);
- Envie um DELETE onde os IDs a serem excluídos estão agrupados na URL (ou seja, "/ records / 1; 2; 3");
- De forma não REST, envie um objeto JSON personalizado contendo os IDs marcados para exclusão.
Todas as opções são menos do que ideais.
Esta parece ser uma área cinzenta da convenção REST.
api
rest
backbone.js
Donald Taylor
fonte
fonte
Respostas:
/records/1;2;3
” - Portanto, uma resposta 2xx a isso pode fazer com que eles limpem o cache/records/1;2;3
; não purga/records/1
,/records/2
ou/records/3
; proxy para uma resposta 410/records/1;2;3
, ou outras coisas que não fazem sentido do seu ponto de vista.records=[1,2,3]
to/delete-requests
) e pesquisar o recurso criado (especificado peloLocation
cabeçalho da resposta) para descobrir se sua solicitação foi aceita, rejeitada ou está em andamento ou foi concluído. Isso é útil para operações de longa duração. Outra forma é enviar umaPATCH
solicitação ao recurso de lista ,/records
, cujo corpo contém uma lista de recursos e ações a serem executadas nesses recursos (em qualquer formato que você deseja oferecer suporte). Isso é útil para operações rápidas em que o código de resposta da solicitação pode indicar o resultado da operação.Tudo pode ser conseguido mantendo-se dentro das restrições de REST, e geralmente a resposta é transformar o "problema" em um recurso e fornecer a ele uma URL.
Portanto, operações em lote, como excluir aqui, ou POSTAR vários itens em uma lista, ou fazer a mesma edição em uma faixa de recursos, podem ser manipuladas criando uma lista de "operações em lote" e POSTANDO sua nova operação nela.
Não se esqueça, REST não é a única maneira de resolver qualquer problema. “REST” é apenas um estilo arquitetônico e você não precisa aderir a ele (mas você perde alguns benefícios da Internet se não o fizer). Eu sugiro que você dê uma olhada nesta lista de arquiteturas de API HTTP e escolha aquela que mais se adequa a você. Apenas fique ciente do que você perderá se escolher outra arquitetura e tome uma decisão informada com base em seu caso de uso.
Existem algumas respostas ruins para esta pergunta sobre Padrões para manipulação de operações em lote em serviços da Web REST? que têm muitos votos positivos, mas devem ser lidos também.
fonte
DELETE
solicitação, o que quer que esteja entre o solicitante e o servidor pensará que um único recurso, no URL especificado, está sendo excluído. Strings de consulta são partes opacas da URL para esses dispositivos, portanto, não importa como você especifica sua API, elas não têm acesso a esse conhecimento, portanto, não podem se comportar de maneira diferente.DELETE
solicitação é proibido. Não faça isso. Se você fizer isso, comerei seus filhos. Nom nom nom.Se
GET /records?filteringCriteria
retornar a matriz de todos os registros que correspondem aos critérios,DELETE /records?filteringCriteria
poderá excluir todos esses registros.Nesse caso, a resposta à sua pergunta seria
DELETE /records?id=1&id=2&id=3
.fonte
GET /records?id=1&id=2&id=3
que não significa “conseguir os três registros com IDs 1, 2 & 3”, que significa “tirar o único recurso com o caminho URL / registros? id = 1 & id = 2 & id = 3”, que pode ser uma imagem de um nabo, um texto simples documento contendo o número "42" em chinês, ou pode não existir./records?id=1
e/records?id=2
são enviadas e suas respostas armazenadas em cache por algum intermediário (por exemplo, seu navegador ou ISP). Se a Internet sabia o que seu aplicativo queria dizer com isso, então é lógico que uma solicitação de/records?id=1&id=2
poderia ser retornada pelo cache simplesmente mesclando (de alguma forma) os dois resultados que já possui, sem ter que perguntar ao servidor de origem. Mas isso não é possível./records?id=1&id=2
pode ser inválido (apenas 1 ID permitido por solicitação) ou pode retornar algo completamente diferente (um nabo).id[]=1&id[]=2
ouid=1&id=2
na string de consulta para representar uma matriz de valores, essa string de consulta representa exatamente isso. E eu acho que é extremamente comum e uma boa prática ter a string de consulta representando um filtro. Além disso, se você permitir exclusões e atualizações, não armazene em cache asGET
solicitações. Se você fizer isso, os clientes ficarão obsoletos.Acho que o Mozilla Storage Service SyncStorage API v1.5 é uma boa maneira de excluir vários registros usando REST.
Exclui uma coleção inteira.
Exclui vários BSOs de uma coleção com uma única solicitação.
ids : exclui BSOs da coleção cujos ids estão na lista separada por vírgulas fornecida. Um máximo de 100 ids podem ser fornecidos.
Exclui o BSO no local fornecido.
http://moz-services-docs.readthedocs.io/en/latest/storage/apis-1.5.html#api-instructions
fonte
Sim, até agora só encontrei um guia de design da API REST que menciona operações em lote (como uma exclusão de lote): o guia de design da API do Google .
Este guia menciona a criação de métodos "personalizados" que podem ser associados por meio de um recurso usando dois-pontos, por exemplo
https://service.name/v1/some/resource/name:customVerb
, também menciona explicitamente operações em lote como caso de uso:Portanto, você pode fazer o seguinte de acordo com o guia de API do Google:
... para deletar vários itens do seu recurso de coleção.
fonte
If the HTTP verb used for the custom method does not accept an HTTP request body (GET, DELETE), the HTTP configuration of such method must not use the body clause at all,
no capítulo Método personalizado. Mas aGET accounts.locations.batchGet
API é o método GET com corpo. Isso é estranho. developers.google.com/my-business/reference/rest/v4/…POST
método http usado e apenas o método personalizado é nomeadobatchGet
. Acho que o Google faz isso para (a) seguir a regra de que todos os métodos personalizados precisam serPOST
(veja minha resposta) e (b) para tornar mais fácil para as pessoas colocarem um "filtro" no corpo para que você não precise escape ou codifique o filtro como nas strings de consulta. a desvantagem, é claro, é que isso não é mais armazenável em cache ...https://service.name/v1/some/resource/name:customVerb
não é RESTful por definição.Permiti uma substituição total de uma coleção, por exemplo,
PUT ~/people/123/shoes
onde o corpo é a representação da coleção inteira.Isso funciona para pequenas coleções filho de itens em que o cliente deseja revisar os itens e remover alguns e adicionar outros e, em seguida, atualizar o servidor. Eles podem PUT uma coleção vazia para deletar tudo.
Isso significaria
GET ~/people/123/shoes/9
que ainda permaneceria no cache mesmo que um PUT o excluísse, mas isso é apenas um problema de cache e seria um problema se outra pessoa excluísse o sapato.Minhas APIs de dados / sistemas sempre usam ETags em vez de tempos de expiração para que o servidor seja atingido em cada solicitação e eu exijo os cabeçalhos de versão / simultaneidade corretos para alterar os dados. Para APIs que são somente leitura e alinhadas com visualização / relatório, eu uso tempos de expiração para reduzir ocorrências na origem, por exemplo, um placar pode durar 10 minutos.
Para coleções muito maiores, como
~/people
, tendo a não precisar de várias exclusões, o caso de uso tende a não surgir naturalmente e, portanto, um único DELETE funciona bem.No futuro, e por experiência com a construção de APIs REST e enfrentando os mesmos problemas e requisitos, como auditoria, eu estaria inclinado a usar apenas verbos GET e POST e projetar em torno de eventos, por exemplo, POST um evento de mudança de endereço, embora eu suspeite que virá com seu próprio conjunto de problemas :)
Eu também permitiria que os desenvolvedores de front-end criassem suas próprias APIs que consomem APIs de back-end mais rígidas, uma vez que muitas vezes há razões práticas e válidas do lado do cliente pelas quais eles não gostam de designs de API REST estritos "fanáticos por Fielding" e para produtividade e motivos de camadas de cache.
fonte