Uma operação RESTful 'PUT' retornará algo

437

Eu queria saber quais são as opiniões das pessoas sobre uma PUToperação RESTful que não retorna nada (nulo) no corpo da resposta.

AwkwardCoder
fonte

Respostas:

615

A especificação HTTP ( RFC 2616 ) possui várias recomendações aplicáveis. Aqui está a minha interpretação:

  • Código de status HTTP 200 OKpara uma PUT bem-sucedida de uma atualização em um recurso existente. Nenhum corpo de resposta é necessário. (De acordo com a Seção 9.6 , 204 No Contenté ainda mais apropriado.)
  • Código de status HTTP 201 Createdpara uma PUT bem-sucedida de um novo recurso, com o URI mais específico para o novo recurso retornado no campo Cabeçalho do local e quaisquer outros URIs e metadados relevantes do recurso ecoados no corpo da resposta. ( Seção 10.2.2 da RFC 2616 )
  • Código de status HTTP 409 Conflictpara um PUT que é bem sucedido devido a um 3 rd modificação -party, com uma lista de diferenças entre a tentativa de atualização e o recurso atual no corpo da resposta. ( Seção 10.4.10 da RFC 2616 )
  • Código de status HTTP 400 Bad Requestpara uma PUT sem êxito, com texto em idioma natural (como inglês) no corpo da resposta que explica por que a PUT falhou. ( Seção 10.4 da RFC 2616 )
PAUSE do sistema
fonte
25
@stian Interessante! Isso parece bastante presunçoso da parte do Mozilla, já que não encontro nada na RFC 2616 (principalmente as seções 10.2 Successful 2xx e 10.2.1 200 OK ) que excluem especificamente o uso de 200PUT, DELETE ou qualquer outro método. Perdi alguma coisa? Como a Mozilla se tornar o chefe do W3 e da IETF? ;) Ou talvez eles nunca tenham ouvido falar do Princípio da Robustez da Postel.
system PAUSE
52
@stian: Essa frase foi removida em 3 de fevereiro de 2013. Provavelmente porque alguém leu sobre isso aqui. ;) developer.mozilla.org/pt-BR/docs/HTTP/…
Christian Strempfer 10/13
6
A semântica do método PUT é ignorar qualquer estado atual em que o recurso esteja, portanto, retornar um conflito 409 para uma PUT sem êxito devido a uma modificação de terceiros, só faz sentido se a solicitação for condicional.
Pedro Werneck
8
@systemPAUSE Ótima resposta. Um pequeno ponto: se você não retornará um corpo de resposta a uma operação bem-sucedida, sugiro o uso exclusivo de um 204. Alguns clientes (jQuery Ajax, por exemplo) engasgam se esperam uma resposta de comprimento diferente de zero, mas não a recebem. Você pode ver um exemplo disso nesta pergunta .
22414 Nick_w
3
Possivelmente, o RFC2616 foi atualizado desde que isso foi respondido. Em nenhum lugar em 9.6 é mencionado No response body neededem relação a um 200. De fato, o corpo da resposta não é mencionado em relação a um PUT. Só declaraIf an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.
james
164

Ao contrário da maioria das respostas aqui, acho que o PUT deve retornar o recurso atualizado (além do código HTTP, é claro).

O motivo pelo qual você desejaria retornar o recurso como uma resposta para a operação PUT é que, quando você envia uma representação de recurso para o servidor, o servidor também pode aplicar algum processamento a esse recurso, para que o cliente queira saber como esse recurso parece que após a solicitação foi concluída com êxito. (caso contrário, ele terá que emitir outra solicitação GET).

LiorH
fonte
3
"o servidor também pode aplicar algum processamento a este recurso": sou novo nisso. Isso é realmente RESTful?
Raedwald 28/08/12
22
@Raedwald, com certeza. O REST não exige que todo o recurso seja atualizado em uma PUT, embora seja geralmente recomendado. Alguns campos podem não fazer sentido para atualizar - a data de criação ou a data da última modificação, por exemplo, provavelmente não devem ser incluídas no corpo da PUT, mas provavelmente serão alteradas como resultado da PUT. Dito isto, eu não concordo com LiorH que um PUT deve resultar em um retorno do recurso; Eu exigiria um GET após o PUT para obter o recurso atualizado.
Randolpho
19
O @Randolpho REST não exige que todo o recurso seja atualizado em um PUT , não deve ser o caso de um PATCH?
Marco Ciambrone 14/10
14
@MarcoCiambrone Sim, concordo e retrocedo meu comentário anterior. Alterei minha melodia no REST e PUT - PUT sempre deve ser idempotente e nunca deve ser usado para uma atualização parcial. O POST é a única alternativa, a menos que PATCH seja suportado; nesse caso, PATCH pode ser uma boa alternativa. PATCH é um novo verbo, no entanto, e pode não ser suportado por algumas estruturas do lado do servidor.
Randolpho
2
A resposta foi escrita bem antes da rfc7231, mas a seção 4.3.4 deixa claro "O método PUT solicita que o estado do recurso de destino seja criado ou substituído pelo estado definido pela representação incluída na carga útil da mensagem de solicitação"
aaaaaa
3

Eu acho que é possível que o servidor retorne conteúdo em resposta a um PUT. Se você estiver usando um formato de envelope de resposta que permita dados carregados de sidel (como o formato consumido por dados de brasa), também poderá incluir outros objetos que podem ter sido modificados por acionadores de banco de dados etc. (Os dados carregados de sideload devem explicitamente reduzir número de solicitações e este parece ser um ótimo local para otimizar.)

Se eu apenas aceitar o PUT e não tiver nada a relatar, utilizarei o código de status 204 sem corpo. Se tenho algo a relatar, uso o código de status 200 e incluo um corpo.

shaunc
fonte
2

A especificação HTTP / 1.1 (seção 9.6) discute os códigos de resposta / erro apropriados. No entanto, ele não aborda o conteúdo da resposta.

O que você esperaria? Um código de resposta HTTP simples (200 etc.) parece direto e inequívoco para mim.

Brian Agnew
fonte
Sim, mas e se você quiser verificar se os dados inseridos no db após um PUT ou POST realmente representam os dados verdadeiros que você deseja. Seria melhor se o HTTP pudesse enviar de volta o corpo da resposta.
Tnkh 26/09/19
1
@tnkh o que você sugere é absolutamente uma idéia horrível. Faça uma chamada GET separada após uma atualização bem-sucedida para alcançar o que deseja. Para garantir o desempenho, introduza uma camada de armazenamento em cache se você estiver enfrentando problemas neste departamento. Não podemos resolver esses problemas brincando com o tipo de lógica 'tudo corre'. Não mexa com princípios de programação 'sólidos' e básicos que devem ser de bom senso no ano de 2020. É uma vergonha!
XDS
@XDS Eu reconheço sua primeira parte do comentário. Mas não consigo parar de revirar os olhos depois disso. Comentário divertido
tnkh
Obrigado por explicar por que você acha hilário.
XDS
2

Se o back-end da API REST for um banco de dados relacional SQL,

  1. você deve ter RowVersion em todos os registros que podem ser atualizados (para evitar o problema de atualização perdida )
  2. você sempre deve retornar uma nova cópia do registro após PUT (para obter a nova RowVersion ).

Se você não se importa com atualizações perdidas ou se deseja forçar seus clientes a fazer um GET imediatamente após um PUT, não retorne nada do PUT.

John Henckel
fonte
1

Código de resposta HTTP 201 para "Criado" junto com um cabeçalho "Local" para apontar para onde o cliente pode encontrar o recurso recém-criado.

dc360
fonte
5
Objectos colocados não são (ou não deveria ser) os recursos recém-criados
kdazzle
9
O @kdazzle PUT pode certamente ser um recurso recém-criado, e muitas vezes seria. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser
3
Só para explicar meu comentário um pouco melhor. PUT significa, coloque este item neste local específico, substituindo o que está lá no momento (se aplicável).
user1751825
3
Certo, "substituindo o que existe atualmente" é a frase-chave. Ele já deveria existir e está sendo substituído. PUT não deve ser para criar novos recursos.
21764 Kevin
3
@KevinM Como no último documento RFC rfc7231 , ele diz que os recursos podem ser criados: "O método PUT solicita que o estado do recurso de destino seja criado ou substituído [...]" e o motivo pelo qual você pensa que o PUT não pode criar novo recurso é porque você não sabe necessariamente a localização do novo recurso. Mas se você souber sua localização / identificador, ele poderá ser criado se ainda não estiver lá.
Leo Lei
0

Eu usei a API RESTful em meus serviços, e aqui está a minha opinião: primeiro precisamos obter uma visão comum: PUTé usado para atualizar um recurso que não é criado ou obtido.

Eu defini recursos com: Stateless resourcee Stateful resource:

  • Recursos sem estado Para esses recursos, basta retornar o HttpCode com corpo vazio, basta.

  • Recursos com estado Por exemplo: a versão do recurso. Para esse tipo de recurso, você deve fornecer a versão quando quiser alterá-la. Portanto, retorne o recurso completo ou a versão ao cliente, para que o cliente não precise enviar uma solicitação de obtenção após a ação de atualização.

Mas , por um serviço ou sistema, mantê-losimple,clearly,easy to use and maintainé a coisa mais importante.

Bruce
fonte
6
"PUT é usado para atualizar um recurso que não é criado ou obtido." - isso não é verdade nem comum. Por especificação, PUT pode criar o recurso. Clear = seguindo as especificações conhecidas.
Imre Pühvel
-3

Assim como um corpo de solicitação vazio está de acordo com o objetivo original de uma solicitação GET e o corpo de resposta vazio está de acordo com o objetivo original de uma solicitação PUT.

AnthonyWJones
fonte
-3

parece ok ... embora eu ache uma indicação rudimentar de sucesso / fracasso / tempo publicado / # bytes recebidos / etc. seria preferível.

editar: eu estava pensando na linha da integridade dos dados e / ou manutenção de registros; metadados, como um hash MD5 ou registro de data e hora para o tempo recebido, podem ser úteis para grandes arquivos de dados.

Jason S
fonte
1
Que tal 200 OK no cabeçalho de resposta de status? Você acha que basta dizer: "Funcionou bem, obrigado?"
21413 AnthonyWJones
o cabeçalho de resposta deve conter o código de status, e sim estamos a falar de HTTP neste momento :)
AwkwardCoder
-4

Idealmente, ele retornaria uma resposta de sucesso / falha.

cgp
fonte
13
Não no corpo da resposta, no entanto. O código de status HTTP é o local para isso. Talvez se há um erro de algumas informações de erro estendidas poderia ser devolvido na bidy resposta
o arquétipo Paul
-4

Há uma diferença entre o cabeçalho e o corpo de uma resposta HTTP. PUT nunca deve retornar um corpo, mas deve retornar um código de resposta no cabeçalho. Basta escolher 200 se foi bem-sucedido e 4xx se não. Não existe um código de retorno nulo. Por que você quer fazer isso?

AlexanderJohannesen
fonte