Acho que você poderia usar um método POST ou PATCH para lidar com isso, pois eles normalmente projetam para isso.
Usar um POST
método normalmente é usado para adicionar um elemento quando usado no recurso de lista, mas você também pode oferecer suporte a várias ações para esse método. Veja esta resposta: Como atualizar uma coleção de recursos REST . Você também pode oferecer suporte a diferentes formatos de representação para a entrada (se eles corresponderem a uma matriz ou a um único elemento).
Nesse caso, não é necessário definir seu formato para descrever a atualização.
Usar um PATCH
método também é adequado, uma vez que as solicitações correspondentes correspondem a uma atualização parcial. De acordo com RFC5789 ( http://tools.ietf.org/html/rfc5789 ):
Vários aplicativos que estendem o protocolo HTTP (Hypertext Transfer Protocol) requerem um recurso para fazer modificações parciais de recursos. O método HTTP PUT existente permite apenas a substituição completa de um documento. Esta proposta adiciona um novo método HTTP, PATCH, para modificar um recurso HTTP existente.
Nesse caso, você deve definir seu formato para descrever a atualização parcial.
Eu acho que neste caso, POST
e PATCH
são bastante semelhantes, já que você realmente não precisa descrever a operação a ser feita para cada elemento. Eu diria que depende do formato da representação a enviar.
O caso de PUT
é um pouco menos claro. Na verdade, ao usar um método PUT
, você deve fornecer a lista completa. Na verdade, a representação fornecida na solicitação será em substituição ao recurso de lista um.
Você pode ter duas opções em relação aos caminhos do recurso.
- Usando o caminho do recurso para a lista de documentos
Nesse caso, você precisa fornecer explicitamente o link dos documentos com um fichário na representação fornecida na solicitação.
Aqui está um exemplo de rota para isso /docs
.
O conteúdo dessa abordagem pode ser para o método POST
:
[
{ "doc_number": 1, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 2, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 3, "binder": 5, (other fields in the case of creation) },
(...)
]
- Usando o caminho de sub-recurso do elemento de ligação
Além disso, você também pode considerar aproveitar sub-rotas para descrever o link entre documentos e fichários. As dicas sobre a associação entre um documento e um fichário não precisam ser especificadas no conteúdo da solicitação.
Aqui está um exemplo de rota para isso /binder/{binderId}/docs
. Nesse caso, o envio de uma lista de documentos com um método POST
ou PATCH
os anexará ao fichário com o identificador binderId
após ter criado o documento se ele não existir.
O conteúdo dessa abordagem pode ser para o método POST
:
[
{ "doc_number": 1, (other fields in the case of creation) },
{ "doc_number": 2, (other fields in the case of creation) },
{ "doc_number": 3, (other fields in the case of creation) },
(...)
]
Em relação à resposta, cabe a você definir o nível de resposta e os erros a serem retornados. Vejo dois níveis: o nível de status (nível global) e o nível de carga útil (nível mais fino). Também cabe a você definir se todas as inserções / atualizações correspondentes à sua solicitação devem ser atômicas ou não.
Nesse caso, você pode aproveitar o status HTTP. Se tudo correr bem, você ganha um status 200
. Caso contrário, outro status, como 400
se os dados fornecidos não estão corretos (por exemplo, o id do fichário não é válido) ou outro.
Nesse caso, um status 200
será retornado e cabe à representação da resposta descrever o que foi feito e onde eventualmente ocorrerão erros. ElasticSearch tem um ponto de extremidade em sua API REST para atualização em massa. Isso pode lhe dar algumas idéias neste nível: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/bulk.html .
Você também pode implementar um processamento assíncrono para lidar com os dados fornecidos. Nesse caso, o status do HTTP retornado será 202
. O cliente precisa puxar um recurso adicional para ver o que acontece.
Antes de terminar, também gostaria de observar que a especificação OData aborda a questão das relações entre entidades com o recurso denominado links de navegação . Talvez você possa dar uma olhada nisso ;-)
O link a seguir também pode ajudá-lo: https://templth.wordpress.com/2014/12/15/designing-a-web-api/ .
Espero que ajude você, Thierry
GET /docs
e recupero todos os documentos em um fichário específicoGET /docs?binder_id=x
,. Para excluir um subconjunto dos recursos, devo chamarDELETE /docs?binder_id=x
ou devo chamarDELETE /docs
com um{"binder_id": x}
no corpo da solicitação? Você usariaPATCH /docs?binder_id=x
para uma atualização em lote ou apenasPATCH /docs
e passaria pares?Você provavelmente precisará usar POST ou PATCH, porque é improvável que uma única solicitação que atualize e crie vários recursos seja idempotente.
Fazer
PATCH /docs
é definitivamente uma opção válida. Você pode achar que usar os formatos de patch padrão é complicado para seu cenário específico. Não tenho certeza sobre isso.Você pode usar 200. Você também pode usar 207 - Multi Status
Isso pode ser feito de forma RESTful. A chave, na minha opinião, é ter algum recurso projetado para aceitar um conjunto de documentos para atualizar / criar.
Se você usar o método PATCH, acho que sua operação deve ser atômica. ou seja, eu não usaria o código de status 207 e relataria sucessos e falhas no corpo da resposta. Se você usar a operação POST, a abordagem 207 é viável. Você terá que projetar seu próprio corpo de resposta para comunicar quais operações tiveram êxito e quais falharam. Não conheço nenhum padronizado.
fonte
This can be done in a RESTful way
que você quer dizer a atualização e criar deve ser feito separadamente?PUT ing
PUT /binders/{id}/docs
Crie ou atualize e relacione um único documento a um ficháriopor exemplo:
PATCH ing
PATCH /docs
Crie documentos se eles não existirem e relacione-os a ficháriospor exemplo:
Incluirei informações adicionais mais tarde, mas, por enquanto, se você quiser, dê uma olhada em RFC 5789 , RFC 6902 e William Durand's Please. Não remende como uma entrada de blog idiota .
fonte
docs
e associá-losbinders
. O cliente deseja criar fichários se eles não existirem e fazer a associação se existirem. Em um único pedido em massa.Em um projeto em que trabalhei, resolvemos esse problema implementando algo que chamamos de solicitações 'em lote'. Definimos um caminho
/batch
onde aceitamos json no seguinte formato:A resposta tem o código de status 207 (Multi-Status) e se parece com isto:
Você também pode adicionar suporte para cabeçalhos nesta estrutura. Implementamos algo que se mostrou útil, que são variáveis para usar entre as solicitações em um lote, o que significa que podemos usar a resposta de uma solicitação como entrada para outra.
Facebook e Google têm implementações semelhantes:
https://developers.google.com/gmail/api/guides/batch
https://developers.facebook.com/docs/graph-api/making-multiple-requests
Quando você deseja criar ou atualizar um recurso com a mesma chamada, eu usaria POST ou PUT dependendo do caso. Se o documento já existe, você deseja que todo o documento seja:
Caso deseje o comportamento da alternativa 1 deverá usar um POST e caso deseje o comportamento da alternativa 2 deverá utilizar PUT.
http://restcookbook.com/HTTP%20Methods/put-vs-post/
Como as pessoas já sugeriram, você também pode optar pelo PATCH, mas prefiro manter a API simples e não usar verbos extras se eles não forem necessários.
fonte
--batch_xxxx
. Existem algumas diferenças cruciais entre as soluções do Google e do Facebook? Além disso, sobre "usar a resposta de uma solicitação como entrada para outra", parece muito interessante, você se importaria de compartilhar mais detalhes? ou que tipo de cenário deve ser usado?