Un'operazione 'PUT' RESTful dovrebbe restituire qualcosa


437

Mi chiedevo quali fossero le opinioni delle persone su un'operazione RESTful PUTche non restituisce nulla (nullo) nel corpo della risposta.

Risposte:


615

La specifica HTTP ( RFC 2616 ) contiene una serie di raccomandazioni applicabili. Ecco la mia interpretazione:

  • Codice di stato HTTP 200 OKper un PUT riuscito di un aggiornamento a una risorsa esistente. Nessun corpo di risposta necessario. (Secondo la Sezione 9.6 , 204 No Contentè ancora più appropriato.)
  • Codice di stato HTTP 201 Createdper un PUT riuscito di una nuova risorsa, con l'URI più specifico per la nuova risorsa restituito nel campo dell'intestazione Ubicazione e qualsiasi altro URI e metadata della risorsa echeggiato nel corpo della risposta. ( RFC 2616 Sezione 10.2.2 )
  • Codice di stato HTTP 409 Conflictper un PUT che non riesce a causa di un 3 ° modifica -party, con un elenco di differenze tra il tentativo di aggiornamento e la risorsa corrente nel corpo della risposta. ( RFC 2616 Sezione 10.4.10 )
  • Codice di stato HTTP 400 Bad Requestper un PUT non riuscito, con testo in lingua naturale (come l'inglese) nel corpo della risposta che spiega perché il PUT non è riuscito. ( RFC 2616 Sezione 10.4 )

25
@stian Interessante! Sembra abbastanza presuntuoso da parte di Mozilla, dal momento che non riesco a trovare nulla in RFC 2616 (in particolare le sezioni 10.2 Successful 2xx e 10.2.1 200 OK ) che escludono specificamente l'uso di 200PUT, DELETE o di qualsiasi altro metodo. Ho dimenticato qualcosa? Come Mozilla che diventa il capo di W3 e IETF? ;) O forse non hanno mai sentito parlare del principio di robustezza di Postel.
sistema PAUSA

52
@stian: quella frase è stata rimossa il 3 febbraio 2013. Probabilmente perché qualcuno l'ha letto qui. ;) developer.mozilla.org/en-US/docs/HTTP/…
Christian Strempfer

6
La semantica del metodo PUT consiste nell'ignorare lo stato corrente della risorsa, quindi restituire un conflitto 409 per un PUT non riuscito a causa di una modifica di terze parti ha senso solo se la richiesta è condizionale.
Pedro Werneck,

8
@systemPAUSE Bella risposta. Un piccolo punto: se non stai per restituire un corpo di risposta a un'operazione riuscita, suggerirei di utilizzare esclusivamente un 204. Alcuni client (ad esempio jQuery Ajax) si strozzeranno se si aspettano una risposta diversa da zero ma non la ottengono. Puoi vedere un esempio di questo in questa domanda .
nick_w,

3
Forse RFC2616 è stato aggiornato da quando è stata data risposta. In nessun punto in 9.6 viene menzionato No response body neededin relazione a un 200. In realtà l'organismo di risposta non è affatto menzionato in relazione a un PUT. Afferma soloIf 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

A differenza della maggior parte delle risposte qui, in realtà penso che PUT dovrebbe restituire la risorsa aggiornata (oltre al codice HTTP ovviamente).

Il motivo per cui si desidera restituire la risorsa come risposta per l'operazione PUT è perché quando si invia una rappresentazione della risorsa al server, il server può anche applicare un po 'di elaborazione a questa risorsa, quindi il client vorrebbe sapere come funziona questa risorsa sembra dopo che la richiesta è stata completata correttamente. (altrimenti dovrà emettere un'altra richiesta GET).


3
"il server può anche applicare un po 'di elaborazione a questa risorsa": sono nuovo questo. È davvero RESTful?
Raedwald,

22
@Raedwald certo che lo è. REST non richiede che l' intera risorsa venga aggiornata su un PUT, sebbene sia generalmente consigliata. Alcuni campi potrebbero non avere senso aggiornare - la data di creazione o la data dell'ultima modifica, ad esempio, probabilmente non dovrebbero essere incluse nel corpo PUT, ma verrebbero probabilmente modificate come risultato del PUT. Detto questo, non sono d'accordo con LiorH sul fatto che un PUT dovrebbe comportare un ritorno della risorsa; Richiederei un OTTENERE dopo il PUT per ottenere la risorsa aggiornata.
Randolpho,

19
@Randolpho REST non richiede che l'intera risorsa venga aggiornata su un PUT non dovrebbe essere il caso di un PATCH?
Marco Ciambrone,

14
@MarcoCiambrone Sì, sono d'accordo e ritraccio il mio commento precedente. Ho cambiato la mia melodia su REST e PUT - PUT dovrebbe sempre essere idempotente e non dovrebbe mai essere usato per un aggiornamento parziale. POST è l'unica alternativa a meno che PATCH non sia supportato, nel qual caso PATCH può essere una buona alternativa. PATCH è un nuovo verbo, tuttavia, e potrebbe non essere supportato da alcuni framework lato server.
Randolpho,

2
La risposta è stata scritta molto prima di rfc7231, ma la sezione 4.3.4 chiarisce che "Il metodo PUT richiede che lo stato della risorsa di destinazione venga creato o sostituito con lo stato definito dalla rappresentazione racchiusa nel payload del messaggio di richiesta"
aaaaaa,

3

Penso che sia possibile per il server restituire contenuti in risposta a un PUT. Se si utilizza un formato di inviluppo della risposta che consente i dati trasferiti lateralmente (come il formato utilizzato dai dati di brace), è possibile includere anche altri oggetti che possono essere stati modificati tramite trigger del database, ecc. N. di richieste, e questo sembra un ottimo posto per ottimizzare.)

Se accetto il PUT e non ho nulla da riferire, utilizzo il codice di stato 204 senza body. Se ho qualcosa da segnalare, utilizzo il codice di stato 200 e includo un corpo.


2

Le specifiche HTTP / 1.1 (sezione 9.6) discute i codici di risposta / errore appropriati. Tuttavia, non tratta il contenuto della risposta.

Cosa ti aspetteresti? Un semplice codice di risposta HTTP (200 ecc.) Mi sembra semplice e chiaro.


Sì, ma cosa succede se si desidera verificare se i dati inseriti in db dopo un PUT o POST rappresentano davvero i dati reali desiderati. Sarebbe meglio se l'HTTP fosse in grado di rispedire il corpo della risposta.
tnkh,

1
@tnkh quello che suggerisci è decisamente un'idea orribile. Effettua una chiamata GET separata dopo un aggiornamento riuscito per ottenere ciò che desideri. Al fine di garantire le prestazioni, introdurre un livello di memorizzazione nella cache se si riscontrano problemi in questo reparto. Non possiamo risolvere questi problemi scherzando con il tipo di logica "tutto va bene". Non scherzare con i principi di programmazione "solidi" e di base che dovrebbero essere di buon senso nel 2020. È una vergogna!
XDS

@XDS Prendo atto della tua prima parte del commento. Ma non posso smettere di roteare gli occhi dopo quello. Commento esilarante
tnkh

Grazie per aver elaborato il motivo per cui lo trovi divertente.
XDS

2

Se il back-end dell'API REST è un database relazionale SQL, quindi

  1. dovresti avere RowVersion in ogni record che può essere aggiornato (per evitare il problema di aggiornamento perso )
  2. dovresti sempre restituire una nuova copia del record dopo PUT (per ottenere la nuova RowVersion ).

Se non ti interessano gli aggiornamenti persi o se vuoi forzare i tuoi clienti a fare un GET immediatamente dopo un PUT, non restituire nulla da PUT.


1

Codice di risposta HTTP di 201 per "Creato" insieme a un'intestazione "Posizione" per indicare dove il client può trovare la risorsa appena creata.


5
Gli oggetti PUT non sono (o non dovrebbero essere) risorse appena create
kdazzle,

9
@kdazzle PUT può certamente essere una risorsa appena creata e spesso lo sarebbe. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser,

3
Giusto per spiegare un po 'meglio il mio commento. PUT significa, metti questo oggetto in questa posizione specifica, sostituendo ciò che è attualmente lì (se applicabile).
user1751825

3
Bene, "sostituire ciò che è attualmente lì" è la frase chiave. Dovrebbe già esistere e verrà sostituito. PUT non dovrebbe essere per la creazione di nuove risorse.
Kevin M,

3
@KevinM Come nell'ultimo documento RFC rfc7231 , dice che è possibile creare risorse: "Il metodo PUT richiede che lo stato della risorsa di destinazione venga creato o sostituito [...]" e il motivo che stai pensando che PUT non possa creare nuova risorsa è perché non si conosce necessariamente la posizione della nuova risorsa. Ma se conosci la sua posizione / identificatore, può essere creato se non è ancora lì.
Leo Lei

0

Ho usato l'API RESTful nei miei servizi, ed ecco la mia opinione: per prima cosa dobbiamo arrivare a una visione comune : PUT viene utilizzato per aggiornare una risorsa non creata o ottenuta.

Ho definito le risorse con: Stateless resourcee Stateful resource:

  • Risorse stateless Per queste risorse, è sufficiente restituire HttpCode con il corpo vuoto, è sufficiente.

  • Risorse con stato Ad esempio: la versione della risorsa. Per questo tipo di risorse, è necessario fornire la versione quando si desidera modificarla, quindi restituire la risorsa completa o restituire la versione al client, quindi il client non deve inviare una richiesta get dopo l'azione di aggiornamento.

Ma , per un servizio o un sistema, conservalosimple , clearly, easy to use and maintainè la cosa più importante.


6
"PUT viene utilizzato per aggiornare una risorsa non creata o ottenuta." - non è vero né comune. Per specifica, PUT può creare la risorsa. Cancella = seguendo le specifiche comunemente note.
Imre Pühvel,

-3

Proprio come un corpo di richiesta vuoto è in linea con lo scopo originale di una richiesta GET e un corpo di risposta vuoto è in linea con lo scopo originale di una richiesta PUT.


-3

sembra ok ... anche se penso che un'indicazione rudimentale di successo / fallimento / tempo pubblicato / # byte ricevuti / ecc. sarebbe preferibile.

modifica: stavo pensando in base all'integrità e / o alla conservazione dei dati; metadati come un hash MD5 o un timestamp per il tempo ricevuto possono essere utili per file di dati di grandi dimensioni.


1
Che ne dici di 200 OK nell'intestazione della risposta di stato? Pensi che sia abbastanza per dire "Ha funzionato bene grazie?"
AnthonyWJones,

l'intestazione della risposta conterrebbe il codice di stato, e sì, stiamo parlando di HTTP a questo punto :)
AwkwardCoder

-4

Idealmente, restituirebbe una risposta di successo / fallimento.


13
Tuttavia, non nel corpo della risposta. Il codice di stato HTTP è il posto per quello. Forse in caso di errore alcune informazioni di errore estese potrebbero essere restituite nella risposta bidy
L'archetipo Paul,

-4

C'è una differenza tra l'intestazione e il corpo di una risposta HTTP. PUT non dovrebbe mai restituire un corpo, ma deve restituire un codice di risposta nell'intestazione. Basta scegliere 200 se ha avuto successo e 4xx in caso contrario. Non esiste un codice di ritorno null. Perchè vuoi fare questo?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.