Quale verbo HTTP dovrei usare per attivare un'azione in un servizio web REST?

62

Sto implementando un servizio web RESTful e una delle azioni disponibili sarà reload . Verrà utilizzato per ricaricare configurazioni, cache, ecc.

Abbiamo iniziato con un semplice GET a un URI come questo: ${path}/cache/reload (non vengono passati parametri, viene chiamato solo l'URI). Sono consapevole che i dati non devono essere modificati con una richiesta GET.

Qual è il verbo corretto da utilizzare per invocare un'azione / comando in un servizio web RESTful?

EDIT: il reload è un comando del servizio web REST che ricarica la propria cache / configurazione / ecc. Non è un metodo che restituisce informazioni al cliente.

FINAL EDIT: Probabilmente quello che sto cercando di fare non è REST, ma è ancora qualcosa che deve essere fatto in questo modo. Il metodo reload è stato solo un esempio reale che rende senso nel campo di applicazione dell'applicazione e la maggior parte delle risposte si sono concentrate su di esso, ma in realtà, ho solo bisogno di sapere quale verbo attivare un'azione che non esegue CRUD, ma cambia ancora dati / stato.

Ho trovato questo asnwer dettagliato su Stack Overflow come argomento: link

    
posta Renato Dinhani 02.11.2014 - 02:17
fonte

9 risposte

21

Non penso che ci sia un verbo proprio per questa azione perché questa transazione non è veramente "RESTful". "S" e "t" stanno per "trasferimento di stato" e nulla viene trasferito qui. O, per dirla in altro modo, con la definizione più rigorosa, i verbi come PUT e POST vengono sempre usati con un nome e "reload" ha solo il verbo.

Questa ricarica potrebbe non essere RESTful, ma potrebbe comunque essere utile e dovrai solo scegliere un modo per farlo e vivere con o spiegare che è insolito. GET è probabilmente il più semplice. C'è una buona dose di scetticismo nei commenti, però, quindi dovresti pensare se questa azione di ricarica è necessaria o meno perché qualcos'altro non sta facendo esattamente quello che dovrebbe fare.

    
risposta data 02.11.2014 - 05:15
fonte
60

Se vuoi essere RESTful non pensare al verbo di eseguire un'azione, pensa allo stato in cui desideri che la risorsa si trovi dopo che il client ha fatto qualcosa.

Quindi, utilizzando uno dei tuoi esempi sopra hai una coda di posta elettronica che sta inviando email. Vuoi che il cliente inserisca la coda di posta elettronica nello stato di pausa o arrestato o qualcosa del genere.

Quindi il client METTA un nuovo stato al server per quella risorsa. Può essere semplice come questo JSON

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

{"status":"paused"}

Il server calcola come passare dallo stato corrente (ad esempio "in esecuzione") allo stato / stato "in pausa".

Se il client esegue un GET sulla risorsa, dovrebbe restituire lo stato in cui si trova attualmente (ad esempio "in pausa").

Il motivo per farlo in questo modo, e perché REST può essere così potente, è che lasci il HOW per arrivare a quello stato sul server.

Il client dice semplicemente "Questo è lo stato in cui dovresti essere ora" e il server calcola come ottenerlo. Potrebbe essere un semplice capovolgimento in un database. Potrebbe richiedere migliaia di azioni. Al cliente non importa, e non deve sapere.

Quindi puoi completamente riscrivere / riprogettare il modo in cui il server fa ciò e il cliente non si cura. Il cliente deve solo essere consapevole dei diversi stati (e delle loro rappresentazioni) di una risorsa, non di quelli interni.

    
risposta data 03.11.2014 - 16:22
fonte
25

Alcune delle altre risposte, inclusa quella accettata, ti suggeriscono di usare un GET (anche se non con molto entusiasmo).

Non sono d'accordo.

Prima di tutto, tutti gli altri che ti dicono che questo non è l'ideale e non sono veramente RESTful sono corretti. In uno scenario REST corretto, stai manipolando le risorse sul server e aggiungendo, aggiornando, eliminando, recuperando, ecc. Quelle risorse. Un PUT dovrebbe inviare un payload che rappresenta quale dovrebbe essere la risorsa quando la richiesta è completa e il POST dovrebbe inviare un payload che rappresenta una risorsa da aggiungere al server. E un GET dovrebbe restituire una risorsa sul server.

Hai un RPC (chiamata di procedura remota), che non è RESTful - vuoi fare qualcosa sul server. Quindi, se stai cercando di creare un'API puramente RESTful, dovresti riconsiderare ciò che stai facendo.

Detto questo, a volte hai bisogno di piegare un po 'le regole. Soprattutto se stai sviluppando una API interna che non sarà esposta al pubblico, potresti decidere che ne vale la pena.

Se lo fai, ti consiglierei un PUT o POST, a seconda che l'RPC sia idempotente o meno .

In generale, diciamo che HTTP PUT si associa a SQL UPDATE e che HTTP POST esegue l'associazione a SQL INSERT, ma questo non è strettamente vero. Un modo più semplice per dichiarare che l'HTTP PUT dovrebbe essere idempotente e il POST HTTP non deve essere. Ciò significa che puoi chiamare la stessa richiesta PUT tutte le volte che vuoi senza effetti collaterali. Una volta che l'hai chiamato, è innocuo chiamarlo di nuovo. Ma non dovresti chiamare ripetutamente le richieste POST a meno che tu non intenda: ogni POST cambia di nuovo i dati sul server.

Nel tuo caso, se hai bisogno di avere questa funzione di ricarica, ti consiglio un PUT perché sembra identrio. Ma ti esorto ancora a considerare quello che gli altri hanno detto di non averne bisogno.

    
risposta data 03.11.2014 - 22:00
fonte
5

POST e PUT sono i verbi HTTP utilizzati per inviare un'entità a un server web. Con PUT , l'entità presentata è la (nuova) rappresentazione per la risorsa all'URI dato, che non si adatta a ciò che si desidera. POST è per il gestore di moduli tradizionale, in cui l'entità è un dato ausiliario per la risorsa, quindi è il vincitore. L'entità includerebbe il comando o l'azione (ad esempio "action = reload").

Detto questo, il comando in questione probabilmente non dovrebbe essere esposto tramite un'interfaccia REST. Sembra che esista la necessità di "ricaricare" perché i dati possono essere modificati tramite qualche altro canale (ad es. File system, client DB). Le cache dovrebbero essere trasparenti. Inoltre, le richieste HTTP dovrebbero essere atomiche, prendendo in considerazione anche i messaggi inviati su altri canali. Offrire un comando "reload" per le impostazioni di configurazione sembra una complessità inutile; richiedendolo è un design fragile. L'esposizione di "ricarica" per ripulire dopo un aggiornamento tramite un altro canale è sporca perché un canale non contiene l'intera conversazione. Invece, considera uno dei seguenti:

  • effettuare aggiornamenti interamente tramite REST
  • esposizione dei comandi sull'altro canale
  • automatizzare le azioni

Alcune di queste opzioni potrebbero non essere valide, a seconda di quali altre restrizioni esistono.

Vedi anche " PUT vs POST in REST ".

    
risposta data 02.11.2014 - 04:23
fonte
4

Direi perché una richiesta client dovrebbe esplicitamente effettuare una chiamata per aggiornare qualcosa del genere. Sembra che dovrebbe essere una logica nascosta su un'implementazione più tipica di GET (Ie Pull data, ma il servizio effettua un aggiornamento sui dati prima che venga estratto), o da un altro trigger nel back-end lontano dal client.

Dopotutto, i dati / config dovrebbero essere solo aggiornati sulle chiamate successive, quindi mi piacerebbe più indirizzare verso una chiamata lazy vs eager per un aggiornamento dei dati. Ovviamente sto assumendo molto qui, ma vorrei fare un passo indietro per rivalutare la necessità di una tale chiamata esplicita e autonoma.

    
risposta data 02.11.2014 - 03:25
fonte
3

Perché non trattare l'azione come una risorsa. Pertanto, poiché desideri aggiornare la cache, POST eseguirà una nuova azione nel tuo sistema.

Per i puristi, potresti avere un URL dedicato per questo. Si noti che è possibile estendere questo e registrare le azioni effettive in un database (o qualsiasi altra memoria) con data, stato, utente, ecc ... Solo i miei pensieri qui.

Operazione generica a livello di sistema / azioni / {action}

Operazione specifica per un tipo di risorsa / azioni / {resource} / {action}

Operazione specifica per una risorsa / Azioni / {resource} / {id} / {action}

Nel tuo caso, la cache è probabilmente a livello di sistema / Azioni / reload_cache

    
risposta data 28.03.2016 - 23:21
fonte
-1

Questo non è un caso d'uso da manuale ma se vuoi essere in teoria compatibile usa PUT che dovrebbe aggiornare i dati. Non hai però un carico utile. Un semplice GET non sarebbe poi così male in questo caso.

    
risposta data 02.11.2014 - 02:52
fonte
-1

I verbi HTTP non hanno nulla a che fare con REST.

Potresti chiedere quale sarebbe il verbo convenzionale per fare qualche azione, ma ancora, non ha nulla a che fare con REST.

REST è uno stile architettonico, che riguarda principalmente il modo in cui i componenti comunicano tra loro. Definisce un insieme di principi, non un insieme di protocolli o verbi.

Potresti creare nuove risorse con il verbo DELETE, mentre non ha alcun senso e non è convenzionale, può comunque essere completamente RESTFul, purché i vincoli siano soddisfatti.

Per quanto riguarda la tua domanda, non è il verbo, l'URL, il formato del messaggio che determina se il suo REST o meno, ma piuttosto la semantica della definizione dell'API del tuo servizio e il protocollo sottostante. L'operazione "reload" interrompe uno dei vincoli REST? A me sembra che non sia così, quindi puoi usare qualunque VERBO vuoi, non renderà il tuo servizio più o meno RESTful.

Per quanto riguarda il tuo caso d'uso, utilizzerei il verbo GET. Semplicemente perché non c'è VERBO HTTP per tale azione, e in questi casi io uso il verbo GET, solo perché uso HTTP e devo usare un VERBO.

    
risposta data 20.03.2016 - 16:20
fonte
-1

Trovo tutte le risposte molto interessanti e perspicaci. Comunque per la domanda originale c'è una risposta chiara a me, che non mi sembra imbarazzante: Capisci "ricaricare" non come azione, ma come segnale. E un segnale è una risorsa. Quindi in un'API in stile REST sarebbe POST / reloadSignal.

E la pubblicazione di questo segnale attiva l'azione appropriata. Dal punto di vista REST, non penso che sia un problema non archiviare questi segnali (se non necessario per ragioni di business).

    
risposta data 08.05.2018 - 21:18
fonte

Leggi altre domande sui tag