Estou projetando uma API REST pragmática e estou um pouco preocupado com a melhor forma de adicionar entidades existentes a uma coleção. Meu modelo de domínio inclui um projeto que possui uma coleção de sites. Esse é um relacionamento estrito de muitos para muitos e não preciso criar uma entidade que modele explicitamente o relacionamento (por exemplo, ProjectSite).
Minha API permitirá que os consumidores adicionem um site existente a um projeto. Onde estou me desligando é que os únicos dados que realmente preciso são ProjectId e SiteId. Minha ideia inicial foi:
1. POST myapi/projects/{projectId}/sites/{siteId}
Mas eu também pensei em
2. POST myapi/projects/{projectId}/sites
com uma entidade do site enviada como conteúdo JSON.
A opção 1 é simples e funciona, mas não parece muito certa, e eu tenho outros relacionamentos que não podem seguir esse padrão, portanto adiciona inconsistência à minha API.
A opção 2 parece melhor, mas leva a duas preocupações:
- Devo criar um site ou lançar uma exceção se um novo site for publicado (SiteId = 0)?
- Como eu só preciso do ProjectId e do SiteId para criar o relacionamento, o Site pode ser postado com dados ausentes ou incorretos para outras propriedades.
Uma terceira opção é fornecer um terminal simples apenas para criar e excluir o relacionamento. Esse terminal esperaria uma carga útil JSON contendo apenas ProjectId e SiteId.
O que você acha?
fonte
Respostas:
POST é o verbo "acrescentar" e também o verbo "processar". PUT é o verbo "criar / atualizar" (para identificadores conhecidos) e quase parece a escolha certa aqui, porque o URI de destino completo é conhecido.
projectId
esiteId
já existe, então você não precisa "POSTAR para uma coleção" para produzir um novo ID.O problema com o PUT é que ele exige que o corpo seja a representação do recurso que você está colocando. Mas a intenção aqui é anexar ao recurso de coleção "projeto / sites", em vez de atualizar o recurso do site.
E se alguém colocar uma representação JSON completa de um site existente? Você deve atualizar a coleção e atualizar o objeto? Você poderia apoiar isso, mas parece que essa não é a intenção. Como você disse,
Em vez disso, eu tentaria postar a
siteId
coleção e confiar na natureza "anexar" e "processar" do POST:Como você está modificando o recurso de coleção de sites e não o recurso de site , esse é o URI que você deseja. O POST pode saber "anexar / processar" e adicionar o elemento com esse ID ao conjunto de sites do projeto.
Isso ainda deixa a porta aberta para a criação de novos sites para o projeto, aprimorando o JSON e omitindo o ID. "No id" == "criar do zero". Mas se o URI da coleção obtiver um ID e nada mais, ficará bem claro o que precisa acontecer.
Pergunta interessante. :)
fonte
POST
vez dePUT
ouPATCH
aqui é que você não tem toda aSite
entidade para colocar nosites
recurso. Você tem apenas o ID, que requer processamento para adicioná-lo à coleção.Usamos o
Patch
método para coisas assim. O que você deseja fazer é modificar um projeto existente para adicionar um site a ele.Então, algo assim funcionaria
com a entidade Site (s) como JSON / JSONArray no corpo da solicitação.
Dessa forma, você pode usar a mesma URL para modificar partes diferentes do Projeto, se necessário - seu código na implementação deve ser inteligente o suficiente para lidar com essa modificação parcial do recurso.
fonte
{"sites": [], "other-stuff": {}}
, poderá ramificar seu código para lidar com todos esses "sujeitos" com muita facilidade. Realmente depende do seu problema específico, mas eu ainda recomendaria o uso do PATCH, pois ele foi projetado especificamente para esse tipo de coisa.PATCH
Também não esperaria que a entidade completa fosse passada como seu valor aqui, em vez de um ID que aponte para alguma entidade?