DELETE deve ser idempotente.
Se eu excluir http://example.com/account/123, ele excluirá a conta.
Se eu fizer novamente, esperaria um 404, já que a conta não existe mais? E se eu tentar EXCLUIR uma conta que nunca existiu?
DELETE deve ser idempotente.
Se eu excluir http://example.com/account/123, ele excluirá a conta.
Se eu fizer novamente, esperaria um 404, já que a conta não existe mais? E se eu tentar EXCLUIR uma conta que nunca existiu?
Respostas:
Em todos os casos (além dos problemas de erro - veja abaixo), a conta não existe mais.
A partir daqui
"Os métodos também podem ter a propriedade" idempotência ", pois ( além de problemas de erro ou expiração ), os efeitos colaterais de N> 0 solicitações idênticas são os mesmos de uma única solicitação. Os métodos GET, HEAD, PUT e DELETE compartilham Além disso, os métodos OPTIONS e TRACE NÃO DEVEM ter efeitos colaterais e, portanto, são inerentemente idempotentes ".
O bit principal dos efeitos colaterais de N> 0 pedidos idênticos é o mesmo que para um único pedido.
Você está certo ao esperar que o código de status seja diferente, mas isso não afeta o conceito principal de idempotência - você pode enviar a solicitação mais de uma vez sem alterações adicionais no estado do servidor.
Idempotent é sobre o efeito da solicitação, não sobre o código de resposta que você obtém.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 diz:
Os métodos também podem ter a propriedade "idempotência", pois (além de problemas de erro ou expiração) os efeitos colaterais de N> 0 pedidos idênticos são os mesmos que para um único pedido.
Embora você possa obter um código de resposta diferente, o efeito do envio de solicitações N + 1 DELETE para o mesmo recurso pode ser considerado o mesmo.
A distinção importante é que idempotente se refere a efeitos colaterais , não a todos os efeitos ou respostas. Se você fizer DELETE http://example.com/account/123
isso, o efeito é que a conta 123 agora é excluída do servidor. Esse é o único efeito, o único e único muda para o estado do servidor. Agora, digamos que você faça a mesma DELETE http://example.com/account/123
solicitação novamente, o servidor responderá de maneira diferente, mas seu estado é o mesmo.
Não é como a solicitação DELETE decidiu alterar o estado do servidor de uma maneira diferente, porque a conta estava ausente, como remover outra conta ou deixar um log de erros. Não, você pode chamar a mesma solicitação DELETE um milhão de vezes e pode ter certeza de que o servidor está no mesmo estado em que estava na primeira vez em que você o chamou .
Sim. Independentemente do código de resposta.
Da mais recente RFC para HTTP 1.1 (ênfase minha):
Os métodos idempotentes são diferenciados porque a solicitação pode ser repetida automaticamente se ocorrer uma falha na comunicação antes que o cliente possa ler a resposta do servidor. Por exemplo, se um cliente enviar uma solicitação PUT e a conexão subjacente for fechada antes que qualquer resposta seja recebida, o cliente poderá estabelecer uma nova conexão e tentar novamente a solicitação idempotente. Ele sabe que a repetição da solicitação terá o mesmo efeito pretendido, mesmo que a solicitação original tenha sido bem-sucedida, embora a resposta possa ser diferente.
Diz explicitamente que a resposta pode ser diferente. Mais importante, ele aponta a razão do conceito: se uma ação é idempotente, o cliente pode repetir a ação quando encontrar algum erro e sabe que não irá travar nada ao fazê-lo; caso contrário, o cliente precisará fazer uma consulta adicional (possivelmente GET
) para verificar se a anterior é eficaz, antes de repetir a ação com segurança. Enquanto o servidor puder fazer essa garantia, a ação será idempotente. Citação de outro comentário :
A idempotência da computação é sobre a robustez de um sistema. Como as coisas podem falhar (por exemplo, falta de rede), quando uma falha é detectada, como você se recupera? A recuperação mais fácil é apenas fazê-lo novamente, mas isso só funciona se fazê-lo novamente for idempotente. Por exemplo,
discard(x)
é idempotente, maspop()
não é. É tudo sobre recuperação de erros.
Eu acho que a mesma coisa, 404 - Conta não existe.
Você poderia argumentar que 400 - Bad Request. Mas, no sentido de REST, o objeto no qual você solicitou a execução de uma ação não existe. Isso se traduz em 404.
Citado na minha outra resposta aqui :
Historicamente, o RFC 2616, publicado em 1999, era as especificações HTTP 1.1 mais referenciadas. Infelizmente, sua descrição sobre a idempotência foi vaga , o que deixa espaço para todos esses debates. Mas essas especificações foram substituídas pela RFC 7231. Citado na RFC 7231, seção 4.2.2 Métodos Idempotentes , ênfase minha:
Um método de solicitação é considerado "idempotente" se o EFEITO NO SERVIDOR pretendido de várias solicitações idênticas com esse método for o mesmo que o efeito de uma única solicitação. Dos métodos de solicitação definidos por esta especificação, PUT, DELETE e métodos de solicitação seguros são idempotentes .
Portanto, está escrito nas especificações, idempotency tem tudo a ver com o efeito no servidor. O primeiro DELETE retornando um 204 e o subsequente DELETE retornando 404, esse código de status diferente NÃO torna o DELETE não idempotente. Usar esse argumento para justificar um retorno 204 subsequente é simplesmente irrelevante.
OK, então não se trata de idempotência. Mas então uma pergunta de acompanhamento pode ser: e se ainda optarmos por usar o 204 no DELETE subsequente? Tudo bem?
Boa pergunta. A motivação é compreensível: permitir que o cliente ainda atinja o resultado pretendido, sem se preocupar com o tratamento de erros. Eu diria que retornar 204 no subsequente DELETE é uma "mentira branca" do lado do servidor amplamente inofensiva, que o lado do cliente não notará imediatamente a diferença. É por isso que existem pessoas fazendo isso na natureza e ainda funciona. Lembre-se de que essa mentira pode ser considerada semanticamente estranha, porque "GET / inexistente" retorna 404, mas "DELETE / inexistente" fornece 204; nesse momento, o cliente descobriria que seu serviço não está totalmente em conformidade com seção 6.5.4 404 não encontrado .
Mas então, a maneira pretendida sugerida pela RFC 7231, ou seja, retornando 404 no DELETE subsequente, não deve ser um problema em primeiro lugar. Muitos outros desenvolvedores escolheram fazer isso. Isso é presumivelmente porque, qualquer cliente que implemente HTTP DELETE (ou qualquer método HTTP, nesse caso), não assumirá cegamente que o resultado sempre será bem-sucedido 2xx. E então, assim que o desenvolvedor começar a considerar o tratamento de erros, o 404 Not Found seria um dos primeiros erros a serem lembrados. Nesse ponto, ele / ela esperava concluir que, é semanticamente seguro para uma operação HTTP DELETE ignorar um erro 404. Problema resolvido.