Que verbos HTTP devo usar para acionar uma ação em um serviço da Web REST?

62

Estou implementando um serviço da web RESTful e uma das ações disponíveis será reload . Ele será usado para recarregar configurações, cache, etc.

Começamos com um GET simples para um URI assim: ${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?

EDIT: O recarregamento é um comando do serviço web REST que recarrega seu próprio cache / configuration / etc. Não é um método que retorna informações para o cliente.

FINAL EDIT: Provavelmente o que eu estou tentando fazer não é REST, mas ainda é algo que precisa ser feito desta forma. O método reload foi apenas um exemplo real que faz sentido no escopo do aplicativo e a maioria das respostas focadas nele, mas na verdade, eu só precisava saber qual verbo disparar uma ação que não faz o CRUD, mas ainda muda dados / estado.

Encontrei esta descrição detalhada no Stack Overflow sobre o assunto: link

    
por Renato Dinhani 02.11.2014 / 02:17
fonte

9 respostas

21

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, colocando de outra forma, pela definição mais estrita, os verbos como PUT e POST são sempre usados com um substantivo e "reload" apenas tem o verbo.

Este recarregamento pode não ser RESTful, mas ainda pode ser útil e você terá apenas uma maneira de fazê-lo e viver com ou explicar que é incomum. GET é provavelmente o mais simples. Há uma quantidade razoável de ceticismo nos comentários, portanto, você deve pensar se essa ação de recarga é necessária porque outra coisa não está fazendo exatamente o que deveria estar fazendo.

    
por 02.11.2014 / 05:15
fonte
60

Se você quiser ser RESTful, não pense no verbo para executar uma ação, pense no estado em que deseja que o recurso esteja após o cliente ter feito alguma coisa.

Portanto, usando um dos seus exemplos acima, você tem uma fila de e-mails que está enviando e-mails. Você quer que o cliente coloque essa fila de e-mails no estado de pausa ou parada ou algo assim.

Assim, o cliente PUTs um novo estado para o servidor para esse recurso. Pode ser tão simples quanto este JSON

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

O servidor descobre como sair do estado atual (digamos "em execução") para o estado / estado "pausado".

Se o cliente fizer um GET no recurso, ele deverá retornar o estado em que se encontra atualmente (digamos, "pausado").

A razão para fazer isso desta maneira, e porque o REST pode ser tão poderoso, é que você deixa o HOW para 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 flip em um banco de dados. Pode requerer milhares de ações. O cliente não se importa e não precisa saber.

Assim, você pode reescrever completamente / reprojetar como o servidor faz isso e o cliente não se importa. O cliente só precisa estar ciente dos diferentes estados (e suas representações) de um recurso, não de nenhum dos internos.

    
por 03.11.2014 / 16:22
fonte
25

Algumas das outras respostas, incluindo a que foi aceita, recomendam que você use um GET (embora não muito entusiasticamente).

Eu não concordo.

Primeiro de tudo, todos os outros dizendo que isso não é ideal e não é realmente RESTful estão corretos. Em um cenário RESTful apropriado, você está manipulando recursos no servidor e adicionando, atualizando, excluindo, recuperando, etc. esses recursos. Um 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ê quer 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 as regras um pouco. Especialmente se você estiver desenvolvendo uma API interna que não será exposta ao público, você pode decidir que a compensação vale a pena.

Se você fizer isso, eu recomendaria um PUT ou POST, dependendo se o RPC é ou não idempotente ou não .

Em geral, dizemos que o HTTP PUT mapeia para o SQL UPDATE e que o HTTP POST mapeia para o SQL INSERT, mas isso não é estritamente verdadeiro. Uma forma mais pura de afirmar que HTTP PUT deve ser idempotente e HTTP POST não precisa ser. Isso significa que você pode chamar a mesma solicitação PUT quantas vezes quiser sem efeitos colaterais. Uma vez que você ligou uma vez, é inofensivo ligar novamente. Mas você não deve chamar repetidamente as solicitações POST, a menos que você queira - cada POST altera os dados no servidor novamente.

No seu caso, se você precisar dessa função de recarga, eu recomendaria um PUT porque parece que é idempotente. Mas eu ainda gostaria que você considerasse o que os outros disseram sobre não precisar disso.

    
por 03.11.2014 / 22:00
fonte
5

POST e PUT são os verbos HTTP usados para enviar uma entidade para um servidor da web. Com PUT , a entidade enviada é a representação (nova) do recurso no URI especificado, que não se ajusta ao que você deseja. POST é para o manipulador de formulários tradicional, em que a entidade é dados auxiliares para o recurso, então esse é o vencedor. A entidade incluiria o comando ou ação (por exemplo, "ação = recarregar").

Dito isto, o comando em questão provavelmente não deve ser exposto através de uma interface REST. Parece que a necessidade de "recarregar" surge porque os dados podem ser alterados através de algum outro canal (por exemplo, sistema de arquivos, cliente de banco de dados). 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 "reload" para configurações parece uma complexidade desnecessária; exigir que seja um design frágil. Expor "reload" para limpar depois de uma atualização através de outro canal está sujo porque um canal não contém toda a conversa. Em vez disso, considere um de:

  • fazendo atualizações inteiramente via REST
  • expondo o (s) comando (s) ao outro canal
  • automatizando as ações

Algumas dessas opções podem não ser viáveis, dependendo de quais outras restrições existem.

Veja também " PUT vs POST no REST ".

    
por 02.11.2014 / 04:23
fonte
4

Eu diria por que uma solicitação do cliente precisaria fazer uma chamada para atualizar algo assim. Parece que isso deve ser uma lógica oculta em uma implementação mais típica de GET (ou seja, dados Pull, mas o serviço faz uma atualização nos dados antes de ser extraído) ou por outro acionador no back-end do cliente.

Afinal de contas, o data / config só precisaria estar atualizado nas chamadas subseqüentes, então eu me inclinaria mais para uma chamada preguiçosa versus ansiosa por uma atualização de dados. Obviamente, estou assumindo muito aqui, mas gostaria de dar um passo atrás para reavaliar a necessidade de uma chamada tão explícita e independente.

    
por 02.11.2014 / 03:25
fonte
3

Por que não tratar a ação como um recurso? Então, como você quer atualizar o cache, você colocaria uma nova ação em seu sistema.

Para puristas, você poderia ter urls dedicados para isso. Observe que você poderia 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 genérica em todo o sistema / actions / {action}

Operação específica para um tipo de recurso / actions / {resource} / {action}

Operação específica para um recurso / actions / {resource} / {id} / {action}

No seu caso, o cache provavelmente é todo o sistema / actions / reload_cache

    
por 28.03.2016 / 23:21
fonte
-1

Este não é um caso de uso de livro didático, mas se você quiser ser teoricamente compatível, use o PUT, que deve atualizar os dados. Você não tem carga útil embora. Um simples GET não seria tão ruim nesse caso.

    
por 02.11.2014 / 02:52
fonte
-1

Os verbos HTTP não têm nada a ver com o REST.

Você pode perguntar qual seria o VERB convencional para fazer alguma ação, mas ainda assim, não tem nada a ver com o REST.

REST é um estilo de arquitetura, que é principalmente sobre como os componentes se comunicam entre si. Ele define um conjunto de princípios, não um conjunto de protocolos ou verbos.

Você pode criar novos recursos com o verbo DELETE, embora não faça sentido e não seja convencional, ele ainda pode ser completamente RESTFul, desde que as restrições sejam atendidas.

Quanto à sua pergunta, não é o verbo, a URL, o formato da mensagem que determina se o seu REST ou não, mas sim a semântica da definição da API do seu serviço e do protocolo subjacente. A operação "reload" quebra alguma das restrições REST? Parece-me que não, então você pode usar qualquer verbo que você quiser, não vai fazer o seu serviço mais ou menos RESTful.

Quanto ao seu caso de uso, usaria o verbo GET. Simplesmente porque não há HTTP VERB para tal ação, e nesses casos eu uso o verbo GET, só porque eu uso HTTP e tenho que usar algum VERB.

    
por 20.03.2016 / 16:20
fonte
-1

Acho todas as respostas muito interessantes e perspicazes. No entanto, para a pergunta original, há uma resposta clara para mim, que não parece estranha: Entenda "recarregar" não como uma ação, mas como um sinal. E um sinal é um recurso. Então, em uma API de estilo REST, seria POST / reloadSignal.

E postar este sinal aciona a ação apropriada. Do ponto de vista do REST, não acho que seja um problema não armazenar esses sinais (se não for necessário por motivos comerciais).

    
por 08.05.2018 / 21:18
fonte

Tags