'Melhor' prática para uma resposta tranquila ao POST

217

Portanto, nada de novo aqui, estou apenas tentando obter algum esclarecimento e parece que não consigo encontrar nenhum em outros posts.

Estou criando um novo recurso com repulsa, digamos:

/books (POST)

com um corpo:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Eu sei que devo retornar um 201 (criado) com um cabeçalho de localização do novo recurso:

Location: /books/12345

A pergunta que não consigo responder por mim mesma é o que o servidor deve retornar no corpo.

Eu sempre fiz esse tipo de resposta:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Eu fiz isso por alguns motivos:

  1. Eu escrevi api para estruturas de front-end como angularjs. No meu caso particular, estou usando recursos angulares e geralmente preciso apenas da identificação do recurso para localizá-lo. Se eu não retornasse o ID no corpo da resposta, seria necessário analisá-lo no cabeçalho Location.
  2. Em um GET de todos os livros, geralmente retorno o objeto inteiro, não apenas o ID. Nesse sentido, meu código de cliente não precisa diferenciar de onde obter o ID (cabeçalho ou corpo do local).

Agora eu sei que estou realmente na área cinzenta aqui, mas a maioria das pessoas está dizendo que devolver todo o recurso é uma prática 'ruim'. Mas e se o servidor alterar / adicionar informações ao recurso. Definitivamente adiciona o ID, mas também pode adicionar outras coisas, como um carimbo de data / hora. No caso de eu não retornar o recurso inteiro, é realmente melhor fazer um POST, retornar o ID e fazer com que o cliente execute um GET para obter o novo recurso.

perdido na tradução
fonte
Pessoalmente, prefiro o corpo vazio para as respostas do POST. O valor do cabeçalho RESTful Location não deve ser um URI (identificador de recurso exclusivo)? Talvez você deva usá-lo como um ID e não analisá-lo para descobrir um ID interno do servidor. Os consumidores da API RESTful da IMO devem navegar usando os hiperlinks fornecidos e não o caminho de criação, adivinhando onde um servidor específico localiza recursos ... E, afinal, o cliente já não sabe o estado do recurso que acabou de criar? repeti-lo consome um desperdício de recursos de rede.
ch4mp 22/02/19
1
Para criar / inserir, Estado 201 - CRIADO, Header Localização → localhost: 8080 / funcionários / 1 (Ver: aqui )
Hassan Tareq

Respostas:

129

Retornar o objeto inteiro em uma atualização não parece muito relevante, mas mal consigo entender por que retornar o objeto inteiro quando ele é criado seria uma prática ruim em um caso de uso normal. Isso seria útil pelo menos para obter o ID facilmente e obter os registros de data e hora, quando relevante. Na verdade, esse é o comportamento padrão obtido quando se anda com o Rails.

Realmente não vejo nenhuma vantagem em retornar apenas o ID e fazer uma solicitação GET depois, para obter os dados que você poderia obter com o seu POST inicial.

De qualquer forma, desde que sua API seja consistente, acho que você deve escolher o padrão que melhor se adapte às suas necessidades. Não há nenhuma maneira correta de como criar uma API REST, imo.

Daniel Perez
fonte
26
Eu sei que isso é antigo, mas posso dar um argumento convincente para usar um GET após o seu POST. Na especificação http / 1.1, qualquer ferramenta histórica pode ignorar as configurações de cache passadas de volta da sua resposta GET ... por isso, se o usuário usar o botão voltar no navegador para retornar a esta página depois de atualizá-la com o POST, poderá usar obsoleto dados em cache do GET original. Então, se você reutilizar o GET, então você pode atualizar o cache e obter uma melhor instantâneo de como a página olhou quando eles deixaram ...
Sombreado
8
@ Shaded Se a API também foi projetada para ser usada por aplicativos, seu argumento para fazer duas solicitações não é válido. Lá, você geralmente armazena em cache os dados mantendo objetos de um tipo de modelo na memória - o que normalmente é feito com a resposta para solicitações POST. E, em relação aos navegadores, a resposta em uma solicitação POST realmente não dói, desde que ainda exista um ponto de extremidade da API GET.
Jeehut
Eu assino o que Daniel declara aqui. Mesmo se você verificar estruturas maduras como o Spring Data, elas sempre retornam o objeto inteiro após persistir. Eu acho que é uma boa prática, como em você cliente que você vai economizar uma ida e volta do servidor para obter as mesmas informações
frandevel
205

O retorno do novo objeto se encaixa no princípio REST de "Interface Uniforme - Manipulação de Recursos por meio de Representações". O objeto completo é a representação do novo estado do objeto que foi criado.

Há uma referência realmente excelente para o design da API, aqui: Práticas recomendadas para projetar uma API RESTful pragmática

Inclui uma resposta para sua pergunta aqui: Atualizações e criação devem retornar uma representação de recurso

Diz:

Para impedir que um consumidor da API precise acessar a API novamente para obter uma representação atualizada, faça com que a API retorne a representação atualizada (ou criada) como parte da resposta.

Parece bem pragmático para mim e se encaixa no princípio REST que mencionei acima.

Grahamesd
fonte
6
que tal retornar todo o conjunto de objetos relevantes? Desta forma, possível classificação pode ser server-side feito, e isso facilita front-end implementação
phil294
2
Mas essas práticas recomendadas não são as melhores. O estatuto do autor que HATEOAS, que é importante igual a outros princípios, não deve ser usado porque "não está pronto". O HATEOAS nunca estará "pronto", porque todos os princípios RESTful são apenas princípios de design de arquitetura, não implementação específica. A referência citada é sobre a visão do autor sobre a API RESTful, que não é RESTful por causa da queda do HATEOAS. É por isso que esta não é a melhor referência :)
marcinn
1
@ marcinn - você notará que a pergunta original tinha aspas em torno de 'Melhor', eu acho, porque há muita opinião nessa área. A referência que eu apontei é algo que eu achei prático. Se você tem uma referência melhor, compartilhe-a. Estou sempre aberto a aprender mais.
grahamesd 13/09/19
@grahamesd Uma implementação é diferente do princípio / padrão do projeto de arquitetura. Ninguém pode esperar que o HATEOAS esteja pronto algum dia, mas há uma chance de alguém criar uma implementação aceitável por muitos. Vinay também escreveu sobre o mapeamento de métodos http para URLs e operações específicas (CRUD), afirmou que a versão por prefixação de URLs é mais pragmática, escreveu que a filtragem por parâmetros de consulta é um caminho a percorrer ... tudo bem, mas tudo isso tem pouco a ver. fazer com a arquitetura RESTful. Ele escreveu sobre algum tipo de contrato. Isso é bom para a API HTTP, mas não chame isso de RESTful.
marcinn
@grahamesd Aqui estão algumas mensagens que explicam esta: - medium.com/@andrea.chiarelli/... - restfulapi.net
marcinn