Estou implementando um serviço web RESTful e uma das ações disponíveis será reload
. Será usado para recarregar configurações, cache, etc.
Começamos com um GET
URI simples como este: ${path}/cache/reload
(nenhum parâmetro é passado, apenas o URI é chamado). Estou ciente de que os dados não devem ser modificados com uma solicitação GET.
Qual é o verbo correto a ser usado para chamar uma ação / comando em um serviço da web RESTful?
O recarregamento é um comando do serviço da web REST que recarrega seu próprio cache / configuração / etc. Não é um método que retorna informações ao cliente.
Provavelmente o que estou tentando fazer não é o REST, mas ainda é algo que precisa ser feito dessa maneira. O reload
método era apenas um exemplo real que faz sentido no escopo do aplicativo e com a maioria das respostas focadas nele, mas, na verdade, eu só precisava saber qual verbo acionar uma ação que não faz CRUD, mas ainda altera os dados / Estado.
Encontrei esta resposta detalhada no Stack Overflow sobre o assunto: https://stackoverflow.com/questions/16877968/
Respostas:
Eu não acho que exista um verbo adequado para essa ação, porque essa transação não é realmente "RESTful". O "s" e "t" significam "transferência de estado" e nada está sendo transferido aqui. Ou, dito de outra maneira, pela definição mais estrita, os verbos como PUT e POST são sempre usados com um substantivo e "recarregar" apenas possui o verbo.
Essa recarga pode não ser RESTful, mas ainda pode ser útil e você terá apenas uma maneira de fazer isso e conviver ou explicar que é incomum. GET é provavelmente o mais simples. Porém, há bastante ceticismo nos comentários; portanto, você deve pensar se essa ação de recarregamento é necessária ou não, porque outra coisa não está fazendo exatamente o que deveria estar fazendo.
fonte
Se você deseja ser RESTful, não pense no verbo para executar uma ação, pense no estado em que deseja que o recurso esteja depois que o cliente tiver feito algo.
Portanto, usando um de seus exemplos acima, você tem uma fila de e-mails que está enviando e-mails. Você deseja que o cliente coloque essa fila de emails no estado de pausa ou parada ou algo assim.
Portanto, o cliente coloca um novo estado no servidor para esse recurso. Pode ser tão simples quanto esse JSON
O servidor descobre como passar do status atual (por exemplo, "em execução") para o status / estado "em pausa".
Se o cliente fizer um GET no recurso, ele retornará o estado em que está atualmente (diga "pausado").
O motivo para fazê-lo dessa maneira e por que o REST pode ser tão poderoso é que você deixa o COMO chegar a esse estado no servidor.
O cliente apenas diz "Este é o estado em que você deve estar agora" e o servidor descobre como conseguir isso. Pode ser um simples golpe em um banco de dados. Pode exigir milhares de ações. O cliente não se importa e não precisa saber.
Assim, você pode reescrever / reprojetar completamente como o servidor faz isso e o cliente não se importa. O cliente precisa apenas estar ciente dos diferentes estados (e suas representações) de um recurso, não de nenhum dos internos.
fonte
GET
é um verbo completamente inapropriado para uso.PUT
é o verbo mais apropriado, pois a operação pode ser considerada como a atualização do "status recarregado" do cache para "recarregado".Algumas das outras respostas, incluindo a aceita, aconselham você a usar um GET (embora não com muito entusiasmo).
Discordo.
Primeiro de tudo, todos os outros dizendo que isso não é o ideal e que realmente não são RESTful estão corretos. Em um cenário RESTful adequado, você está manipulando recursos no servidor e adicionando, atualizando, excluindo, recuperando etc. esses recursos. Uma PUT deve enviar uma carga útil que represente qual deve ser o recurso quando a solicitação for concluída e o POST deve enviar uma carga útil que represente um recurso a ser adicionado ao servidor. E um GET deve retornar um recurso no servidor.
Você tem um RPC (chamada de procedimento remoto), que não é RESTful - você deseja fazer algo no servidor. Portanto, se você estiver tentando criar uma API puramente RESTful, reconsidere o que está fazendo.
Dito isto, às vezes você precisa dobrar um pouco as regras. Especialmente se você estiver desenvolvendo uma API interna que não será exposta ao público, você pode decidir que a troca vale a pena.
Se o fizer, eu recomendaria um PUT ou POST, dependendo se o RPC é ou não idempotente .
Em geral, dizemos que HTTP PUT mapeia para SQL UPDATE e que HTTP POST mapeia para SQL INSERT, mas isso não é rigorosamente verdade. Uma maneira mais pura de afirmar que o HTTP PUT deve ser idempotente e o HTTP POST não precisa. Isso significa que você pode chamar a mesma solicitação PUT quantas vezes quiser, sem efeitos colaterais. Depois de ligar uma vez, é inofensivo chamá-lo novamente. Mas você não deve chamar repetidamente solicitações de POST, a menos que queira - cada POST altere os dados no servidor novamente.
No seu caso, se você precisar ter essa função de recarga, recomendo um PUT porque parece idempotente. Mas eu ainda insistiria que você considerasse o que os outros disseram sobre não precisar disso.
fonte
POST
ePUT
são os verbos HTTP usados para enviar uma entidade para um servidor web. ComPUT
, a entidade enviada é a (nova) representação do recurso no URI fornecido, que não se encaixa no que você deseja.POST
é para o manipulador de formulários tradicional, onde a entidade é dados auxiliares do recurso, então esse é o vencedor. A entidade incluiria o comando ou ação (por exemplo, "action = reload").Dito isto, o comando em questão provavelmente não deve ser exposto por meio de uma interface REST. Parece que a necessidade de "recarregar" surge porque os dados podem ser alterados por outro canal (por exemplo, sistema de arquivos, cliente DB). Os caches devem ser transparentes. Além disso, as solicitações HTTP devem ser atômicas, levando em consideração as mensagens enviadas por outros canais. Oferecer um comando "recarregar" para definições de configuração parece uma complexidade desnecessária; exigindo que seja um design quebradiço. Expor "recarregar" para limpeza após uma atualização por outro canal está sujo, porque um canal não contém a conversa inteira. Em vez disso, considere um dos seguintes:
Algumas dessas opções podem não ser viáveis, dependendo de outras restrições.
Consulte também " PUT vs POST no REST ".
fonte
Eu argumentaria por que uma solicitação de cliente precisaria explicitamente fazer uma chamada para atualizar algo assim. Parece que isso deve ser uma lógica oculta em uma implementação mais típica do GET (ou seja, puxar dados, mas o serviço atualiza os dados antes de serem puxados) ou por outro gatilho no back-end do cliente.
Afinal, os dados / configuração precisariam estar atualizados apenas nas chamadas subseqüentes, portanto, eu me inclinaria mais para uma chamada preguiçosa ou ansiosa por uma atualização de dados. Obviamente, estou assumindo muito aqui, mas eu daria um passo para trás para reavaliar a necessidade de uma ligação tão explícita e independente.
fonte
email_queue/stop_sending_emails
. Estou apenas dando um comando para algo usando uma interface RESTful.Por que não tratar a ação como um recurso. Portanto, como você deseja atualizar o cache, você POSTARIA uma nova ação em seu sistema.
Para os puristas, você pode ter um URL dedicado para isso. Observe que você pode estender isso e registrar as ações reais em um banco de dados (ou qualquer armazenamento) com data, status, usuário, etc ... Apenas meus pensamentos aqui.
Operação / ações genéricas em todo o sistema / {action}
Operação específica para um tipo de recurso / ações / {recurso} / {ação}
Operação específica para um recurso / ações / {recurso} / {id} / {ação}
No seu caso, o cache provavelmente é de todo o sistema / actions / reload_cache
fonte
Ao considerar os detalhes de um serviço REST, geralmente é útil considerar esta heurística: como você implementaria isso em um site?
O HTML pode descrever apenas solicitações GET e POST de forma nativa. Então, podemos começar a procurar lá.
É
GET
apropriado? Para responder a essa pergunta, precisamos pensar nas suposições que clientes e componentes intermediários podem fazerGET
. A semântica deGET
são segurosA implicação, portanto, é que os clientes e os componentes intermediários têm o poder de chamar uma solicitação GET com a frequência necessária para satisfazer suas próprias preocupações. As aranhas podem obter recursos indiscriminadamente para atualizar seus índices. Os caches podem ser pré-buscados. Em uma rede não confiável, as mensagens perdidas podem ser repetidas com a frequência necessária para garantir pelo menos uma resposta.
Se essas coisas são caras, talvez você não queira que os clientes enviem essas solicitações a seu critério.
POST
, por outro lado, é efetivamente irrestrito - isso reduz bastante as suposições que os clientes genéricos podem fazer. Você não obtém componentes que fazem solicitações POST especulativas porque eles seriam defeituosos - nada no padrão diz que está tudo bem.PUT
,PATCH
,DELETE
... estes são métodos inseguros com a semântica mais específicos do quePOST
; se eles são ou não apropriados, dependerá do seu modelo de recursos.Uma idéia importante a ser lembrada é que os métodos HTTP pertencem ao domínio do documento (consulte a palestra de Jim Webber, 2011 ). Os efeitos que você está descrevendo provavelmente não fazem parte do domínio do documento, mas são efeitos colaterais invocados quando os documentos são alterados. . Isso lhe dá muita liberdade em termos de como você organiza seus documentos para realizar o trabalho.
fonte