PUT vs. POST in REST

Secondo la specifica HTTP / 1.1:

Il metodo POST viene utilizzato per richiedere che il server di origine accetti l’ quadro inclusa nella richiesta come nuovo subordinato della risorsa identificata Request-URI di Request-Line

In altre parole, il POST è usato per creare .

Il metodo PUT richiede che l’entity framework inclusa sia archiviata Request-URI fornito. Se l’ Request-URI della Request-URI riferisce a una risorsa già esistente, l’ quadro inclusa DOVREBBE essere considerata come una versione modificata di quella che risiede sul server di origine. Se l’ Request-URI della Request-URI non punta a una risorsa esistente e quell’URI può essere definito come una nuova risorsa dall’agente utente richiedente, il server di origine può creare la risorsa con quell’URI. ”

Cioè, PUT è usato per creare o aggiornare .

Quindi, quale dovrebbe essere usato per creare una risorsa? O uno deve supportare entrambi?

Complessivamente:

Sia PUT che POST possono essere utilizzati per la creazione.

Devi chiedere “a cosa stai eseguendo l’azione?” per distinguere ciò che dovresti usare. Supponiamo che tu stia progettando un’API per fare domande. Se si desidera utilizzare il POST, lo si farebbe su un elenco di domande. Se vuoi usare PUT, lo faresti a una particolare domanda.

Possono essere utilizzati entrambi, quindi quale si dovrebbe usare nel mio progetto RESTful:

Non è necessario supportare sia PUT che POST.

Che viene utilizzato è lasciato a voi. Ma ricorda di usare quello giusto a seconda dell’object a cui fai riferimento nella richiesta.

Alcune considerazioni:

  • Nomini i tuoi oggetti URL che crei esplicitamente o lasci decidere al server? Se li chiami, usa PUT. Se lasci decidere al server, usa POST.
  • PUT è idempotente, quindi se Metti un object due volte, non ha alcun effetto. Questa è una bella proprietà, quindi userei PUT quando ansible.
  • Puoi aggiornare o creare una risorsa con PUT con lo stesso URL dell’object
  • Con POST è ansible avere 2 richieste contemporaneamente apportando modifiche a un URL e possono aggiornare parti diverse dell’object.

Un esempio:

Ho scritto quanto segue come parte di un’altra risposta su SO in merito a questo :

INVIARE:

Utilizzato per modificare e aggiornare una risorsa

 POST /questions/ HTTP/1.1 Host: www.example.com/ 

Si noti che quanto segue è un errore:

 POST /questions/ HTTP/1.1 Host: www.example.com/ 

Se l’URL non è stato ancora creato, non dovresti usare POST per crearlo mentre specifichi il nome. Ciò dovrebbe comportare un errore “risorsa non trovata” perché non esiste ancora. Devi risorsa sul server.

Potresti fare qualcosa di simile per creare risorse usando il POST:

 POST /questions HTTP/1.1 Host: www.example.com/ 

Nota che in questo caso il nome della risorsa non è specificato, il nuovo percorso URL degli oggetti ti verrà restituito.

METTERE:

Utilizzato per creare una risorsa o sovrascriverlo. Mentre si specifica il nuovo URL delle risorse.

Per una nuova risorsa:

 PUT /questions/ HTTP/1.1 Host: www.example.com/ 

Per sovrascrivere una risorsa esistente:

 PUT /questions/ HTTP/1.1 Host: www.example.com/ 

Puoi trovare affermazioni sul web che dicono

  • Il POST dovrebbe essere usato per creare una risorsa e PUT dovrebbe essere usato per modificarne uno
  • PUT dovrebbe essere usato per creare una risorsa, e POST dovrebbe essere usato per modificarne uno

Nemmeno è giusto.


È meglio scegliere tra PUT e POST in base all’idempotenza dell’azione.

PUT implica mettere una risorsa – sostituendo completamente ciò che è disponibile all’URL dato con una cosa diversa. Per definizione, un PUT è idempotente. Fallo tutte le volte che vuoi, e il risultato è lo stesso. x=5 è idempotente. È ansible inserire una risorsa indipendentemente dal fatto che esistesse in precedenza, oppure no (ad esempio, per creare o aggiornare)!

Il POST aggiorna una risorsa, aggiunge una risorsa sussidiaria o causa una modifica. Un POST non è idempotente, nel senso che x++ non è idempotente.


Con questo argomento, PUT è per creare quando conosci l’URL della cosa che creerai. Il POST può essere utilizzato per creare quando si conosce l’URL della “fabbrica” ​​o gestore per la categoria di cose che si desidera creare.

così:

 POST /expense-report 

o:

 PUT /expense-report/10929 
  • POST a un URL crea una risorsa secondaria su un URL definito dal server .
  • PUT a un URL crea / sostituisce la risorsa nella sua interezza all’URL definito dal client .
  • PATCH a un URL aggiorna parte della risorsa in quell’URL definito dal client.

Le specifiche rilevanti per PUT e POST sono RFC 2616 §9.5ff.

POST crea una risorsa secondaria, quindi POST a /items crea una risorsa che vive sotto la risorsa /items . Per esempio. /items/1 . L’invio dello stesso pacchetto di posta due volte creerà due risorse.

PUT è per creare o sostituire una risorsa in un URL conosciuto dal client .

Pertanto: PUT è solo un candidato per CREATE in cui il client conosce già l’url prima che la risorsa venga creata. Per esempio. /blogs/nigel/entry/when_to_use_post_vs_put poiché il titolo viene utilizzato come chiave della risorsa

PUT sostituisce la risorsa nell’URL conosciuto se già esiste, quindi l’invio della stessa richiesta due volte non ha alcun effetto. In altre parole, le chiamate a PUT sono idempotenti .

La RFC si legge così:

La differenza fondamentale tra le richieste POST e PUT si riflette nel diverso significato dell’Unità della richiesta. L’URI in una richiesta POST identifica la risorsa che gestirà l’entity framework inclusa. Quella risorsa potrebbe essere un processo di accettazione dei dati, un gateway per qualche altro protocollo o un’ quadro separata che accetta annotazioni. Al contrario, l’URI in una richiesta PUT identifica l’entity framework inclusa nella richiesta: l’agente utente sa quale URI è inteso e il server NON DEVE tentare di applicare la richiesta ad un’altra risorsa. Se il server desidera che la richiesta venga applicata a un URI diverso,

Nota: PUT è stato principalmente utilizzato per aggiornare le risorse (sostituendole nella loro interezza), ma di recente c’è movimento verso l’utilizzo di PATCH per l’aggiornamento delle risorse esistenti, in quanto PUT specifica che sostituisce l’intera risorsa. RFC 5789.

Sommario:

Creare:

Può essere eseguito con PUT o POST nel modo seguente:

METTERE

Crea la nuova risorsa con newResourceId come identificatore, sotto l’URI / risorse o raccolta .

 PUT /resources/ HTTP/1.1 

INVIARE

Crea una nuova risorsa sotto l’URI / risorse o raccolta . Di solito l’identificatore viene restituito dal server.

 POST /resources HTTP/1.1 

Aggiornare:

Può essere eseguito solo con PUT nel seguente modo:

METTERE

Aggiorna la risorsa con existingResourceId come identificatore, sotto l’URI / risorse o raccolta .

 PUT /resources/ HTTP/1.1 

Spiegazione:

Quando si ha a che fare con REST e URI come generale, si ha un generico a sinistra e uno specifico a destra . I generici sono di solito chiamati collezioni e gli oggetti più specifici possono essere chiamati risorse . Si noti che una risorsa può contenere una raccolta .

Esempi:

< - generico - specifico ->

 URI: website.com/users/john website.com - whole site users - collection of users john - item of the collection, or a resource URI:website.com/users/john/posts/23 website.com - whole site users - collection of users john - item of the collection, or a resource posts - collection of posts from john 23 - post from john with identifier 23, also a resource 

Quando usi il POST ti riferisci sempre a una raccolta , quindi ogni volta che dici:

 POST /users HTTP/1.1 

stai postando un nuovo utente alla raccolta degli utenti .

Se vai avanti e prova qualcosa del genere:

 POST /users/john HTTP/1.1 

funzionerà, ma semanticamente stai dicendo che vuoi aggiungere una risorsa alla raccolta john sotto la collezione degli utenti .

Una volta che si utilizza PUT, si fa riferimento a una risorsa oa un singolo object, eventualmente all’interno di una raccolta . Quindi quando dici:

 PUT /users/john HTTP/1.1 

stai dicendo all’aggiornamento del server, o crea se non esiste, la risorsa john sotto la collezione degli utenti .

Spec:

Permettetemi di evidenziare alcune parti importanti delle specifiche:

INVIARE

Il metodo POST viene utilizzato per richiedere che il server di origine accetti l’ quadro inclusa nella richiesta come nuovo subordinato della risorsa identificata dall’URI di richiesta nella riga di richiesta

Quindi, crea una nuova risorsa in una raccolta .

METTERE

Il metodo PUT richiede che l’entity framework inclusa sia archiviata nell’URI di richiesta fornito. Se l’URI della richiesta si riferisce a una risorsa già esistente , l’ quadro inclusa DOVREBBE essere considerata come una versione modificata di quella che risiede sul server di origine. Se l’URI della richiesta non punta a una risorsa esistente e quell’URI può essere definito come una nuova risorsa dall’agente utente richiedente, il server di origine può creare la risorsa con quell’URI. ”

Quindi, creare o aggiornare in base all’esistenza della risorsa .

Riferimento:

  • Spec. HTTP / 1.1
  • Wikipedia – REST
  • Uniform Resource Identifiers (URI): syntax generica e semantica

Mi piacerebbe aggiungere il mio consiglio “pragmatico”. Usa PUT quando conosci l'”id” con il quale l’object che stai salvando può essere recuperato. L’utilizzo di PUT non funzionerà molto bene se è necessario, ad esempio, un ID generato da un database da restituire per consentire future ricerche o aggiornamenti.

Quindi: per salvare un utente esistente o uno in cui il client genera l’ID e si è verificato che l’ID è univoco:

 PUT /user/12345 HTTP/1.1 < -- create the user providing the id 12345 Host: mydomain.com GET /user/12345 HTTP/1.1 <-- return that user Host: mydomain.com 

Altrimenti, usa POST per creare inizialmente l'object e PUT per aggiornare l'object:

 POST /user HTTP/1.1 < --- create the user, server returns 12345 Host: mydomain.com PUT /user/12345 HTTP/1.1 <--- update the user Host: mydomain.com 

POST significa “crea nuovo” come in “Ecco l’input per creare un utente, crearlo per me”.

PUT significa “inserisci, sostituisci se già esiste” come in “Ecco i dati per l’utente 5”.

POST a example.com/users poiché non conosci ancora l’URL dell’utente, vuoi che il server lo crei.

Metti su example.com/users/id poiché vuoi sostituire / creare un utente specifico .

POSTARE due volte con gli stessi dati significa creare due utenti identici con ID diversi. METTENDO due volte con gli stessi dati crea l’utente il primo e lo aggiorna allo stesso stato la seconda volta (senza modifiche). Poiché si finisce con lo stesso stato dopo un PUT, non importa quante volte lo si esegue, si dice che sia “ugualmente potente” ogni volta – idempotente. Questo è utile per riprovare automaticamente le richieste. Non è più “sei sicuro di voler inviare nuovamente” quando premi il pulsante Indietro sul browser.

Un consiglio generale è di usare il POST quando hai bisogno che il server controlli la generazione di URL delle tue risorse. Usa PUT altrimenti. Preferisci PUT su POST.

Usa POST per creare e PUT per aggiornare. È così che lo fa Ruby on Rails, comunque.

 PUT /items/1 #=> update POST /items #=> create 

REST è un concetto di altissimo livello. In effetti, non menziona nemmeno l’HTTP!

Se hai dei dubbi su come implementare REST in HTTP, puoi sempre dare un’occhiata alle specifiche Atom Publication Protocol (AtomPub) . AtomPub è uno standard per la scrittura di servizi web RESTful con HTTP sviluppato da molti luminari HTTP e REST, con alcuni input da Roy Fielding, l’inventore di REST e (co-) inventore dello stesso HTTP.

In effetti, potresti anche essere in grado di utilizzare direttamente AtomPub. Anche se è uscito dalla comunità dei blog, non è in alcun modo limitato al blogging: è un protocollo generico per interagire RESTfully con raccolte arbitrarie (nidificate) di risorse arbitrarie via HTTP. Se è ansible rappresentare la propria applicazione come raccolta nidificata di risorse, è sufficiente utilizzare AtomPub e non preoccuparsi se utilizzare PUT o POST, quali codici di stato HTTP restituire e tutti quei dettagli.

Questo è ciò che AtomPub ha da dire sulla creazione di risorse (sezione 9.2):

Per aggiungere membri a una raccolta, i client inviano richieste POST all’URI della raccolta.

La decisione se utilizzare PUT o POST per creare una risorsa su un server con un’API HTTP + REST è basata su chi possiede la struttura dell’URL. Avere il cliente a conoscenza o partecipare alla definizione, la struttura dell’URL è un accoppiamento non necessario simile agli accoppiamenti indesiderati che sono sorti dalla SOA. La fuga di tipi di accoppiamenti è la ragione per cui REST è così popolare. Pertanto, il metodo corretto da utilizzare è POST. Esistono eccezioni a questa regola e si verificano quando il cliente desidera mantenere il controllo sulla struttura delle risorse delle risorse che distribuisce. Questo è raro e probabilmente significa che qualcos’altro è sbagliato.

A questo punto alcune persone sosterranno che se vengono utilizzati gli URL RESTful , il client conosce l’URL della risorsa e quindi un PUT è accettabile. Dopo tutto, questo è il motivo per cui sono canonici, normalizzati, Ruby on Rails, gli URL di Django sono importanti, guarda l’API di Twitter … blah blah blah. Queste persone hanno bisogno di capire che non esiste un URL riposante e che lo stesso Roy Fielding afferma :

Un’API REST non deve definire nomi o gerarchie di risorse fisse (un accoppiamento ovvio tra client e server). I server devono avere la libertà di controllare il proprio spazio dei nomi. Invece, consentire ai server di istruire i clienti su come build URI appropriati, come avviene nei moduli HTML e nei modelli URI, definendo tali istruzioni all’interno dei tipi di media e delle relazioni di collegamento. [L’insuccesso qui implica che i clienti stiano assumendo una struttura di risorse a causa di informazioni fuori banda, come uno standard specifico del dominio, che è l’equivalente orientato ai dati dell’accoppiamento funzionale di RPC].

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

L’idea di un URL RESTful è in realtà una violazione di REST poiché il server è responsabile della struttura dell’URL e dovrebbe essere libero di decidere come utilizzarlo per evitare l’accoppiamento. Se questo ti confonde, leggi l’importanza della scoperta di sé sul design dell’API.

L’uso di POST per creare risorse viene fornito con una considerazione di progettazione perché il POST non è idempotente. Ciò significa che ripetere un POST diverse volte non garantisce lo stesso comportamento ogni volta. Questo spaventa le persone a usare PUT per creare risorse quando non dovrebbero. Sanno che è sbagliato (il POST è per CREATE) ma lo fanno comunque perché non sanno come risolvere questo problema. Questa preoccupazione è dimostrata nella seguente situazione:

  1. Il client invia una nuova risorsa al server.
  2. Il server elabora la richiesta e invia una risposta.
  3. Il client non riceve mai la risposta.
  4. Il server non è a conoscenza del fatto che il client non abbia ricevuto la risposta.
  5. Il client non ha un URL per la risorsa (quindi PUT non è un’opzione) e ripete il POST.
  6. Il POST non è idempotente e il server …

Il punto 6 è dove le persone si confondono comunemente su cosa fare. Tuttavia, non vi è alcun motivo per creare un kludge per risolvere questo problema. Invece, HTTP può essere utilizzato come specificato in RFC 2616 e il server risponde:

10.4.10 409 Conflitto

La richiesta non può essere completata a causa di un conflitto con lo stato corrente della risorsa. Questo codice è consentito solo in situazioni in cui è previsto che l’utente possa risolvere il conflitto e inviare nuovamente la richiesta. Il corpo della risposta DOVREBBE includere abbastanza

informazioni per l’utente per riconoscere l’origine del conflitto. Idealmente, l’ quadro di risposta includerebbe informazioni sufficienti per l’utente o l’agente utente per risolvere il problema; tuttavia, ciò potrebbe non essere ansible e non è richiesto.

È più probabile che si verifichino conflitti in risposta a una richiesta PUT. Ad esempio, se si utilizzava il controllo delle versioni e l’entity framework che si trova PUT includeva le modifiche a una risorsa che è in conflitto con quelle effettuate da una richiesta precedente (di terze parti), il server potrebbe utilizzare la risposta 409 per indicare che non può completare la richiesta . In questo caso, l’entity framework di risposta probabilmente conterrebbe un elenco delle differenze tra le due versioni in un formato definito dalla risposta Content-Type.

Rispondere con un codice di stato di 409 Conflitto è il ricorso corretto perché :

  • L’esecuzione di un POST di dati con un ID che corrisponde a una risorsa già presente nel sistema è “un conflitto con lo stato corrente della risorsa”.
  • Poiché la parte importante è che il client comprenda che il server ha la risorsa e che intraprende le azioni appropriate. Questa è una “situazione / i in cui è previsto che l’utente possa essere in grado di risolvere il conflitto e inviare nuovamente la richiesta”.
  • Una risposta che contiene l’URL della risorsa con l’ID in conflitto e le precondizioni appropriate per la risorsa fornirebbe “informazioni sufficienti per l’utente o l’agente utente per risolvere il problema”, che è il caso ideale per RFC 2616.

Aggiornamento basato sul rilascio di RFC 7231 su Sostituisci 2616

RFC 7231 è progettato per sostituire 2616 e nella Sezione 4.3.3 descrive la ansible risposta successiva per un POST

Se il risultato dell’elaborazione di un POST equivale a una rappresentazione di una risorsa esistente, un server di origine PU MAY redirect l’agente utente a tale risorsa inviando una risposta 303 (Vedi Altro) con l’identificatore della risorsa esistente nel campo Posizione. Ciò ha il vantaggio di fornire all’agente utente un identificatore di risorsa e di trasferire la rappresentazione tramite un metodo più suscettibile alla memorizzazione nella cache condivisa, sebbene al costo di una richiesta aggiuntiva se l’agente utente non ha già la rappresentazione nella cache.

Ora potrebbe essere tentato di restituire semplicemente un 303 nel caso in cui un POST venga ripetuto. Comunque, l’opposto è vero. Restituire un 303 avrebbe senso solo se più richieste di creazione (creando risorse diverse) restituiscono lo stesso contenuto. Un esempio potrebbe essere un “ringraziamento per aver inviato il messaggio di richiesta” che il cliente non deve scaricare nuovamente ogni volta. RFC 7231 mantiene ancora nella sezione 4.2.2 che il POST non deve essere idempotente e continua a sostenere che il POST dovrebbe essere usato per creare.

Per maggiori informazioni a riguardo, leggi questo articolo .

I like this advice, from RFC 2616’s definition of PUT :

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request — the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource.

This jibes with the other advice here, that PUT is best applied to resources that already have a name, and POST is good for creating a new object under an existing resource (and letting the server name it).

I interpret this, and the idempotency requirements on PUT, to mean that:

  • POST is good for creating new objects under a collection (and create does not need to be idempotent)
  • PUT is good for updating existing objects (and update needs to be idempotent)
  • POST can also be used for non-idempotent updates to existing objects (especially, changing part of an object without specifying the whole thing — if you think about it, creating a new member of a collection is actually a special case of this kind of update, from the collection’s perspective)
  • PUT can also be used for create if and only if you allow the client to name the resource. But since REST clients aren’t supposed to make assumptions about URL structure, this is less in the intended spirit of things.

Both are used for data transmission between client to server, but there are subtle differences between them, which are:

Inserisci qui la descrizione dell'immagine

Analogy:

  • PUT ie take and put where it was.
  • POST as send mail in post office.

inserisci la descrizione dell'immagine qui

In breve:

PUT is idempotent, where the resource state will be the same if the same operation is executed one time or multiple times.

POST is non-idempotent, where the resource state may become different if the operation is executed multiple times as compared to executing a single time.

Analogy with database query

PUT You can think of similar to “UPDATE STUDENT SET address = “abc” where id=”123″;

POST You can think of something like “INSERT INTO STUDENT(name, address) VALUES (“abc”, “xyzzz”);

Student Id is auto generated.

With PUT, if the same query is executed multiple times or one time, the STUDENT table state remains the same.

In case of POST, if the same query is executed multiple times then multiple Student records get created in the database and the database state changes on each execution of an “INSERT” query.

NOTE: PUT needs a resource location (already-resource) on which update needs to happen, whereas POST doesn’t require that. Therefore intuitively POST is meant for creation of a new resource, whereas PUT is needed for updating the already existing resource.

Some may come up with that updates can be performsd with POST. There is no hard rule which one to use for updates or which one to use for create. Again these are conventions, and intuitively I’m inclined with the above mentioned reasoning and follow it.

POST is like posting a letter to a mailbox or posting an email to an email queue. PUT is like when you put an object in a cubby hole or a place on a shelf (it has a known address).

With POST, you’re posting to the address of the QUEUE or COLLECTION. With PUT, you’re putting to the address of the ITEM.

PUT is idempotent. You can send the request 100 times and it will not matter. POST is not idempotent. If you send the request 100 times, you’ll get 100 emails or 100 letters in your postal box.

A general rule: if you know the id or name of the item, use PUT. If you want the id or name of the item to be assigned by the receiving party, use POST.

POST versus PUT

New answer (now that I understand REST better):

PUT is merely a statement of what content the service should, from now on, use to render representations of the resource identified by the client; POST is a statement of what content the service should, from now on, contain (possibly duplicated) but it’s up to the server how to identify that content.

PUT x (if x identifies a resource ): “Replace the content of the resource identified by x with my content.”

PUT x (if x does not identify a resource): “Create a new resource containing my content and use x to identify it.”

POST x : “Store my content and give me an identifier that I can use to identify a resource (old or new) containing said content (possibly mixed with other content). Said resource should be identical or subordinate to that which x identifies.” ” y ‘s resource is subordinate to x ‘s resource” is typically but not necessarily implemented by making y a subpath of x (eg x = /foo and y = /foo/bar ) and modifying the representation(s) of x ‘s resource to reflect the existence of a new resource, eg with a hyperlink to y ‘s resource and some metadata. Only the latter is really essential to good design, as URLs are opaque in REST — you’re supposed to use hypermedia instead of client-side URL construction to traverse the service anyways.

In REST, there’s no such thing as a resource containing “content”. I refer as “content” to data that the service uses to render representations consistently. It typically consists of some related rows in a database or a file (eg an image file). It’s up to the service to convert the user’s content into something the service can use, eg converting a JSON payload into SQL statements.

Original answer (might be easier to read) :

PUT /something (if /something already exists): “Take whatever you have at /something and replace it with what I give you.”

PUT /something (if /something does not already exist): “Take what I give you and put it at /something .”

POST /something : “Take what I give you and put it anywhere you want under /something as long as you give me its URL when you’re done.”

Ruby on Rails 4.0 will use the ‘PATCH’ method instead of PUT to do partial updates.

RFC 5789 says about PATCH (since 1995):

A new method is necessary to improve interoperability and prevent errors. The PUT method is already defined to overwrite a resource with a complete new body, and cannot be reused to do partial changes. Otherwise, proxies and caches, and even clients and servers, may get confused as to the result of the operation. POST is already used but without broad interoperability (for one, there is no standard way to discover patch format support). PATCH was mentioned in earlier HTTP specifications, but not completely defined.

” Edge Rails: PATCH is the new primary HTTP method for updates ” explains it.

Short Answer:

Simple rule of thumb: Use POST to create, use PUT to update.

Long Answer:

POST:

  • POST is used to send data to server.
  • Useful when the resource’s URL is unknown

PUT:

  • PUT is used to transfer state to the server
  • Useful when a resource’s URL is known

Longer Answer:

To understand it we need to question why PUT was required, what were the problems PUT was trying to solve that POST couldn’t.

From a REST architecture’s point of view there is none that matters. We could have lived without PUT as well. But from a client developer’s point of view it made his/her life a lot simpler.

Prior to PUT, clients couldn’t directly know the URL that the server generated or if all it had generated any or whether the data to be sent to the server is already updated or not. PUT relieved the developer of all these headaches. PUT is idempotent, PUT handles race conditions, and PUT lets the client choose the URL.

At the risk of restating what has already been said, it seems important to remember that PUT implies that the client controls what the URL is going to end up being, when creating a resource. So part of the choice between PUT and POST is going to be about how much you can trust the client to provide correct, normalized URL that are coherent with whatever your URL scheme is.

When you can’t fully trust the client to do the right thing, it would be more appropriate to use POST to create a new item and then send the URL back to the client in the response.

The most important consideration is reliability . If a POST message gets lost the state of the system is undefined. Automatic recovery is impossible. For PUT messages, the state is undefined only until the first successful retry.

For instance, it may not be a good idea to create credit card transactions with POST.

If you happen to have auto generated URI’s on your resource you can still use PUT by passing a generated URI (pointing to an empty resource) to the client.

Some other considerations:

  • POST invalidates cached copies of the entire containing resource (better consistency)
  • PUT responses are not cacheable while POST ones are (Require Content-Location and expiration)
  • PUT is less supported by eg Java ME, older browsers, firewalls

In a very simple way I’m taking the example of the Facebook timeline.

Case 1: When you post something on your timeline, it’s a fresh new entry. So in this case they use the POST method because the POST method is non-idempotent.

Case 2: If your friend comment on your post the first time, that also will create a new entry in the database so the POST method used.

Case 3: If your friend edits his comment, in this case, they had a comment id, so they will update an existing comment instead of creating a new entry in the database. Therefore for this type of operation use the PUT method because it is idempotent.*

In a single line, use POST to add a new entry in the database and PUT to update something in the database.

There seems to always be some confusion as to when to use the HTTP POST versus the HTTP PUT method for REST services. Most developers will try to associate CRUD operations directly to HTTP methods. I will argue that this is not correct and one can not simply associate the CRUD concepts to the HTTP methods. Questo è:

 Create => HTTP PUT Retrieve => HTTP GET Update => HTTP POST Delete => HTTP DELETE 

It is true that the R(etrieve) and D(elete) of the CRUD operations can be mapped directly to the HTTP methods GET and DELETE respectively. However, the confusion lies in the C(reate) and U(update) operations. In some cases, one can use the PUT for a create while in other cases a POST will be required. The ambiguity lies in the definition of an HTTP PUT method versus an HTTP POST method.

According to the HTTP 1.1 specifications the GET, HEAD, DELETE, and PUT methods must be idempotent, and the POST method is not idempotent. That is to say that an operation is idempotent if it can be performsd on a resource once or many times and always return the same state of that resource. Whereas a non idempotent operation can return a modified state of the resource from one request to another. Hence, in a non idempotent operation, there is no guarantee that one will receive the same state of a resource.

Based on the above idempotent definition, my take on using the HTTP PUT method versus using the HTTP POST method for REST services is: Use the HTTP PUT method when:

 The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee. The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date). 

In both cases, these operations can be performsd multiple times with the same results. That is the resource will not be changed by requesting the operation more than once. Hence, a true idempotent operation. Use the HTTP POST method when:

 The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client. On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation. 

Conclusione

Do not directly correlate and map CRUD operations to HTTP methods for REST services. The use of an HTTP PUT method versus an HTTP POST method should be based on the idempotent aspect of that operation. That is, if the operation is idempotent, then use the HTTP PUT method. If the operation is non idempotent, then use the HTTP POST method.

the origin server can create the resource with that URI

So you use POST and probably, but not necessary PUT for resource creation. You don’t have to support both. For me POST is perfectly enough. So it is a design decision.

As your quote mentioned, you use PUT for creation of there is no resource assigned to an IRI, and you want to create a resource anyway. For example, PUT /users/123/password usually replaces the old password with a new one, but you can use it to create a password if it does not exist already (for example, by freshly registered users or by restoring banned users).

I’m going to land with the following:

PUT refers to a resource, identified by the URI. In this case, you are updating it. It is the part of the three verbs referring to resources — delete and get being the other two.

POST is basically a free form message, with its meaning being defined ‘out of band’. If the message can be interpreted as adding a resource to a directory, that would be OK, but basically you need to understand the message you are sending (posting) to know what will happen with the resource.


Because PUT and GET and DELETE refer to a resource, they are also by definition idempotent.

POST can perform the other three functions, but then the semantics of the request will be lost on the intermediaries such as caches and proxies. This also applies to providing security on the resource, since a post’s URI doesn’t necessarily indicate the resource it is applying to (it can though).

A PUT doesn’t need to be a create; the service could error if the resource isn’t already created, but otherwise update it. Or vice versa — it may create the resource, but not allow updates. The only thing required about PUT is that it points to a specific resource, and its payload is the representation of that resource. A successful PUT means (barring interference) that a GET would retrieve the same resource.


Edit: One more thing — a PUT can create, but if it does then the ID has to be a natural ID — AKA an email address. That way when you PUT twice, the second put is an update of the first. This makes it idempotent .

If the ID is generated (a new employee ID, for example), then the second PUT with the same URL would create a new record, which violates the idempotent rule. In this case the verb would be POST, and the message (not resource) would be to create a resource using the values defined in this message.

Readers new to this topic will be struck by the endless discussion about what you should do, and the relative absence of lessons from experience. The fact that REST is “preferred” over SOAP is, I suppose, a high-level learning from experience, but goodness we must have progressed from there? It’s 2016. Roy’s dissertation was in 2000. What have we developed? Was it fun? Was it easy to integrate with? To support? Will it handle the rise of smartphones and flaky mobile connections?

According to ME, real-life networks are unreliable. Requests timeout. Connections are reset. Networks go down for hours or days at a time. Trains go into tunnels with mobile users aboard. For any given request (as occasionally acknowledged in all this discussion) the request can fall in the water on its way, or the response can fall in the water on its way back. In these conditions, issuing PUT, POST and DELETE requests directly against substantive resources has always struck me as a little brutal and naive.

HTTP does nothing to ensure reliable completion of the request-response, and that’s just fine because this is properly the job of network-aware applications. Developing such an application, you can jump through hoops to use PUT instead of POST, then more hoops to give a certain kind of error on the server if you detect duplicate requests. Back at the client, you then have to jump through hoops to interpret these errors, refetch, revalidate and repost.

Or you can do this : consider your unsafe requests as ephemeral single-user resources (let’s call them actions). Clients request a new “action” on a substantive resource with an empty POST to the resource. POST will be used only for this. Once safely in possession of the URI of the freshly minted action, the client PUTs the unsafe request to the action URI, not the target resource . Resolving the action and updating the “real” resource is properly the job of your API, and is here decoupled from the unreliable network.

The server does the business, returns the response and stores it against the agreed action URI . If anything goes wrong, the client repeats the request (natural behaviour!), and if the server has already seen it, it repeats the stored response and does nothing else .

You will quickly spot the similarity with promises: we create and return the placeholder for the result before doing anything. Also like a promise, an action can succeed or fail one time, but its result can be fetched repeatedly.

Best of all, we give sending and receiving applications a chance to link the uniquely identified action to uniqueness in their respective environments. And we can start to demand, and enforce!, responsible behaviour from clients: repeat your requests as much as you like, but don’t go generating a new action until you’re in possession of a definitive result from the existing one.

As such, numerous thorny problems go away. Repeated insert requests won’t create duplicates, and we don’t create the real resource until we’re in possession of the data. (database columns can stay not-nullable). Repeated update requests won’t hit incompatible states and won’t overwrite subsequent changes. Clients can (re)fetch and seamlessy process the original confirmation for whatever reason (client crashed, response went missing, etc.).

Successive delete requests can see and process the original confirmation, without hitting a 404 error. If things take longer than expected, we can respond provisionally, and we have a place where the client can check back for the definitive result. The nicest part of this pattern is its Kung-Fu (Panda) property. We take a weakness, the propensity for clients to repeat a request any time they don’t understand the response, and turn it into a strength 🙂

Before telling me this is not RESTful, please consider the numerous ways in which REST principles are respected. Clients don’t construct URLs. The API stays discoverable, albeit with a little change in semantics. HTTP verbs are used appropriately. If you think this is a huge change to implement, I can tell you from experience that it’s not.

If you think you’ll have huge amounts of data to store, let’s talk volumes: a typical update confirmation is a fraction of a kilobyte. HTTP currently gives you a minute or two to respond definitively. Even if you only store actions for a week, clients have ample chance to catch up. If you have very high volumes, you may want a dedicated acid-compliant key value store, or an in-memory solution.

The semantics are supposed be different, in that “PUT”, like “GET” is supposed to be idempotent — meaning, you can the same exact PUT request multiple times and the result will be as if you executed it only once.

I will describe the conventions which I think are most widely used and are most useful:

When you PUT a resource at a particular URL what happens is that it should get saved at that URL, or something along those lines.

When you POST to a resource at a particular URL, often you are posting a related piece of information to that URL. This implies that the resource at the URL already exists.

For example, when you want to create a new stream, you can PUT it to some URL. But when you want to POST a message to an existing stream, you POST to its URL.

As for modifying the properties of the stream, you can do that with either PUT or POST. Basically, only use “PUT” when the operation is idempotent – otherwise use POST.

Note, however, that not all modern browsers support HTTP verbs other than GET or POST.

Most of the time, you will use them like this:

  • POST a resource into a collection
  • PUT a resource identified by collection/:id

Per esempio:

  • POST /items
  • PUT /items/1234

In both cases, the request body contains the data for the resource to be created or updated. It should be obvious from the route names that POST is not idempotent (if you call it 3 times it will create 3 objects), but PUT is idempotent (if you call it 3 times the result is the same). PUT is often used for “upsert” operation (create or update), but you can always return a 404 error if you only want to use it to modify.

Note that POST “creates” a new element in the collection, and PUT “replaces” an element at a given URL, but it is a very common practice to use PUT for partial modifications, that is, use it only to update existing resources and only modify the included fields in the body (ignoring the other fields). This is technically incorrect, if you want to be REST-purist, PUT should replace the whole resource and you should use PATCH for the partial update. I personally don’t care much as far as the behavior is clear and consistent across all your API endpoints.

Remember, REST is a set of conventions and guidelines to keep your API simple. If you end up with a complicated work-around just to check the “RESTfull” box then you are defeating the purpose 😉

While there is probably an agnostic way to describe these, it does seem to be conflicting with various statements from answers to websites.

Let’s be very clear and direct here. If you are a .NET developer working with Web API, the facts are (from the Microsoft API documentation), http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations :

 1. PUT = UPDATE (/api/products/id) 2. MCSD Exams 2014 - UPDATE = PUT, there are **NO** multiple answers for that question period. 

Sure you “can” use “POST” to update, but just follow the conventions laid out for you with your given framework. In my case it is .NET / Web API, so PUT is for UPDATE there is no debate.

I hope this helps any Microsoft developers that read all comments with Amazon and Sun/Java website links.

If you are familiar with database operations, there are

  1. Selezionare
  2. Insert
  3. Aggiornare
  4. Elimina
  5. Merge (Update if already existing, else insert)

I use PUT for Merge and update like operations and use POST for Insertions.

In practice, POST works well for creating resources. The URL of the newly created resource should be returned in the Location response header. PUT should be used for updating a resource completely. Please understand that these are the best practices when designing a RESTful API. HTTP specification as such does not restrict using PUT/POST with a few restrictions for creating/updating resources. Take a look at http://techoctave.com/c7/posts/71-twitter-rest-api-dissected that summarizes the best practices.

Here’s a simple rule:

PUT to a URL should be used to update or create the resource that can be located at that URL.

POST to a URL should be used to update or create a resource which is located at some other (“subordinate”) URL, or is not locatable via HTTP.

POST: Use it for creating new resources. It’s like INSERT (SQL statement) with an auto-incremented ID. In the response part it contains a new generated Id.

POST is also used for updating a record.

PUT: Use it for creating a new resource, but here I know the identity key. It’s like INSERT (SQL statement) where I know in advance the identity key. In the response part it sends nothing.

PUT is also used for updating a resource