http example - PUT vs.POST in REST




patch get (25)

Mentre c'è probabilmente un modo agnostico per descriverli, sembra essere in conflitto con varie affermazioni dalle risposte ai siti web.

Siamo molto chiari e diretti qui. Se sei uno sviluppatore .NET che lavora con Web API, i fatti sono (dalla documentazione dell'API di Microsoft), 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.

Certo, "puoi" usare "POST" per aggiornare, ma segui semplicemente le convenzioni stabilite per te con il tuo framework. Nel mio caso è .NET / Web API, quindi PUT è per UPDATE non c'è dibattito.

Spero che questo aiuti tutti gli sviluppatori Microsoft che leggono tutti i commenti con i link di Amazon e Sun / Java.

Secondo la specifica HTTP / 1.1:

Il metodo POST viene utilizzato per richiedere che il server di origine accetti l'entità 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'entità inclusa sia archiviata Request-URI fornito. Se l' Request-URI della Request-URI riferisce a una risorsa già esistente, l'entità 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?


Ruby on Rails 4.0 userà il metodo 'PATCH' invece di PUT per eseguire aggiornamenti parziali.

RFC 5789 dice di PATCH (dal 1995):

È necessario un nuovo metodo per migliorare l'interoperabilità e prevenire gli errori. Il metodo PUT è già definito per sovrascrivere una risorsa con un nuovo corpo completo e non può essere riutilizzato per eseguire modifiche parziali. In caso contrario, proxy e cache e persino client e server potrebbero confondersi con il risultato dell'operazione. Il POST è già utilizzato, ma senza un'ampia interoperabilità (per esempio, non esiste un modo standard per scoprire il supporto per il formato di patch). PATCH è stato menzionato nelle precedenti specifiche HTTP, ma non completamente definito.

" Edge Rails: PATCH è il nuovo metodo HTTP primario per gli aggiornamenti " lo spiega.


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 costruire 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'entità di risposta includerebbe informazioni sufficienti per l'utente o l'agente utente per risolvere il problema; tuttavia, ciò potrebbe non essere possibile 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'entità 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'entità 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 possibile 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 reindirizzare 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 article .


I lettori nuovi su questo argomento saranno colpiti dall'interminabile discussione su cosa dovresti fare e dalla relativa assenza di lezioni tratte dall'esperienza. Il fatto che REST sia "preferito" rispetto al SOAP è, suppongo, un apprendimento di alto livello dall'esperienza, ma la bontà deve essere progredita da lì? È il 2016. La dissertazione di Roy è stata nel 2000. Che cosa abbiamo sviluppato? Era divertente? È stato facile integrarsi con? Supportare? Gestirà l'ascesa di smartphone e connessioni mobili traballanti?

Secondo ME, le reti della vita reale sono inaffidabili. Richieste di timeout. Le connessioni vengono ripristinate. Le reti scendono per ore o giorni alla volta. I treni vanno nei tunnel con gli utenti mobili a bordo. Per qualsiasi richiesta (come occasionalmente riconosciuta in tutta questa discussione) la richiesta può cadere nell'acqua sulla sua strada, o la risposta può cadere nell'acqua sulla via del ritorno. In queste condizioni, emettere richieste PUT, POST e DELETE direttamente contro risorse sostanziali mi ha sempre colpito come un po 'brutale e ingenuo.

HTTP non fa nulla per assicurare il completamento affidabile della richiesta-risposta, e va bene, perché questo è il compito appropriato delle applicazioni in grado di riconoscere la rete. Sviluppando un'applicazione di questo tipo, puoi passare da un anello all'altro per utilizzare PUT anziché POST, quindi più cerchie per dare un determinato tipo di errore sul server se rilevi richieste duplicate. Tornando al client, devi quindi saltare attraverso i cerchi per interpretare questi errori, recuperare, riconvalidare e ripubblicare.

Oppure puoi farlo : considera le tue richieste non sicure come risorse effimere per utente singolo (chiamiamole azioni). I clienti richiedono una nuova "azione" su una risorsa sostanziale con un POST vuoto alla risorsa. POST sarà usato solo per questo. Una volta in possesso dell'URI dell'azione appena coniata, il client METTA la richiesta non sicura all'URI dell'azione, non alla risorsa di destinazione . Risolvere l'azione e aggiornare la risorsa "reale" è propriamente il lavoro della tua API ed è qui disaccoppiato dalla rete inaffidabile.

Il server fa il business, restituisce la risposta e la memorizza contro l'URI di azione concordato . Se qualcosa va storto, il client ripete la richiesta (comportamento naturale!), E se il server lo ha già visto, ripete la risposta memorizzata e non fa altro .

Scoprirai rapidamente la somiglianza con le promesse: creiamo e restituiamo il segnaposto per il risultato prima di fare qualsiasi cosa. Anche come una promessa, un'azione può avere successo o fallire una volta, ma il suo risultato può essere ripetutamente recuperato.

Meglio ancora, diamo alle applicazioni di invio e ricezione la possibilità di collegare l'azione identificata in modo univoco con l'unicità nei rispettivi ambienti. E possiamo iniziare a chiedere e applicare! Comportamento responsabile da parte dei clienti: ripeti le tue richieste quanto vuoi, ma non generare una nuova azione finché non sei in possesso di un risultato definitivo da quello esistente.

Come tale, numerosi problemi spinosi vanno via. Le richieste di inserimento ripetute non creeranno duplicati e non creeremo la risorsa reale finché non saremo in possesso dei dati. (le colonne del database possono rimanere non annullabili). Le richieste di aggiornamento ripetute non colpiranno stati incompatibili e non sovrascriveranno le successive modifiche. I client possono (ri) recuperare e processare la conferma originale per qualsiasi motivo (il client si è bloccato, la risposta è andata persa, ecc.).

Successive richieste di cancellazione possono vedere ed elaborare la conferma originale, senza colpire un errore 404. Se le cose richiedono più tempo del previsto, possiamo rispondere provvisoriamente e abbiamo un posto dove il cliente può controllare il risultato definitivo. La parte più bella di questo modello è la sua proprietà Kung-Fu (Panda). Prendiamo un punto debole, la propensione per i clienti a ripetere una richiesta ogni volta che non capiscono la risposta e la trasformano in forza :-)

Prima di dirmi che questo non è RESTful, considera i numerosi modi in cui i principi REST sono rispettati. I client non costruiscono URL. L'API rimane individuabile, anche se con un piccolo cambiamento nella semantica. I verbi HTTP sono usati in modo appropriato. Se pensi che questo sia un enorme cambiamento da implementare, posso dirti per esperienza che non lo è.

Se pensi di avere enormi quantità di dati da archiviare, parliamo dei volumi: una tipica conferma di aggiornamento è una frazione di un kilobyte. HTTP ti offre attualmente un minuto o due per rispondere in modo definitivo. Anche se memorizzi solo azioni per una settimana, i clienti hanno ampie possibilità di recuperare il ritardo. Se si dispone di volumi molto elevati, è possibile che si desideri un archivio di valori chiave dedicato compatibile con l'acido o una soluzione in memoria.


In pratica, il POST funziona bene per la creazione di risorse. L'URL della risorsa appena creata deve essere restituito nell'intestazione della risposta Location. PUT dovrebbe essere usato per aggiornare completamente una risorsa. Si prega di comprendere che queste sono le migliori pratiche durante la progettazione di un'API RESTful. Le specifiche HTTP in quanto tali non limitano l'utilizzo di PUT / POST con alcune restrizioni per la creazione / aggiornamento delle risorse. Dai un'occhiata a http://techoctave.com/c7/posts/71-twitter-rest-api-dissected che riassume le migliori pratiche.


Puoi trovare affermazioni sul web che dicono

Nemmeno è giusto.

È meglio scegliere tra PUT e POST in base idempotence 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. È possibile 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

Il più delle volte, li userete in questo modo:

  • POSTARE una risorsa in una raccolta
  • Metti una risorsa identificata dalla collezione /: id

Per esempio:

  • POST / articoli
  • PUT / items / 1234

In entrambi i casi, il corpo della richiesta contiene i dati per la risorsa da creare o aggiornare. Dovrebbe essere ovvio dai nomi delle rotte che il POST non è idempotente (se lo chiami 3 volte creerà 3 oggetti), ma PUT è idempotente (se lo chiami 3 volte il risultato è lo stesso). PUT viene spesso utilizzato per l'operazione "upsert" (creazione o aggiornamento), ma è sempre possibile restituire un errore 404 se si desidera utilizzarlo solo per la modifica.

Nota che POST "crea" un nuovo elemento nella collezione e PUT "sostituisce" un elemento in un dato URL, ma è una pratica molto comune usare PUT per le modifiche parziali, cioè usarlo solo per aggiornare le risorse esistenti e modificare solo i campi inclusi nel corpo (ignorando gli altri campi). Questo è tecnicamente scorretto, se vuoi essere purista di REST, PUT dovrebbe sostituire l'intera risorsa e dovresti usare PATCH per l'aggiornamento parziale. Personalmente non mi interessa molto di quanto il comportamento sia chiaro e coerente su tutti i tuoi endpoint API.

Ricorda, REST è un insieme di convenzioni e linee guida per mantenere la tua API semplice. Se finisci con un complicato work-around solo per controllare la casella "RESTfull", allora stai sconfiggendo lo scopo;)


La considerazione più importante è l' affidabilità . Se un messaggio POST viene perso, lo stato del sistema non è definito. Il recupero automatico è impossibile. Per i messaggi PUT, lo stato non è definito solo fino al primo tentativo riuscito.

Ad esempio, potrebbe non essere una buona idea creare transazioni con carta di credito con POST.

Se ti capita di avere URI generati automaticamente sulla tua risorsa, puoi comunque utilizzare PUT passando un URI generato (che punta a una risorsa vuota) al client.

Alcune altre considerazioni:

  • Il POST invalida le copie memorizzate nella cache dell'intera risorsa contenente (migliore consistenza)
  • Le risposte PUT non sono memorizzabili nella cache mentre quelle POST sono (Richiedi Content-Location and expiration)
  • PUT è meno supportato da es. Java ME, browser più vecchi, firewall

POST è come inviare una lettera a una casella di posta o inviare un'e-mail a una coda di posta elettronica. PUT è come quando metti un oggetto in una tana o in un posto su uno scaffale (ha un indirizzo conosciuto).

Con POST, stai postando all'indirizzo della CODA o della RACCOLTA. Con PUT, stai inserendo l'indirizzo dell'ITEM.

PUT è idempotente. Puoi inviare la richiesta 100 volte e non importa. POST non è idempotente. Se invii la richiesta 100 volte, riceverai 100 e-mail o 100 lettere nella tua casella postale.

Una regola generale: se conosci l'ID o il nome dell'articolo, usa PUT. Se si desidera che l'ID o il nome dell'articolo sia assegnato dalla parte ricevente, utilizzare POST.


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 è possibile 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.


Risposta breve:

Semplice regola empirica: usa POST per creare, usa PUT per aggiornare.

Risposta lunga:

INVIARE:

  • Il POST viene utilizzato per inviare dati al server.
  • Utile quando l'URL della risorsa è sconosciuto

METTERE:

  • PUT viene utilizzato per trasferire lo stato sul server
  • Utile quando l'URL di una risorsa è noto

Risposta più lunga:

Per capirlo abbiamo bisogno di mettere in discussione perché è stato richiesto PUT, quali erano i problemi che PUT stava cercando di risolvere quel POST non poteva.

Dal punto di vista dell'architettura REST non c'è nulla che contenga. Avremmo potuto anche vivere senza PUT. Ma dal punto di vista dello sviluppatore di un cliente ha reso la sua vita molto più semplice.

Prima di PUT, i client non potevano conoscere direttamente l'URL generato dal server o se ne aveva generati tutti o se i dati da inviare al server sono già aggiornati o meno. PUT ha sollevato lo sviluppatore di tutti questi mal di testa. PUT è idempotente, PUT gestisce le condizioni di gara e PUT consente al client di scegliere l'URL.


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

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

La semantica dovrebbe essere diversa, in quel "PUT", come "GET" dovrebbe essere idempotente - nel senso, puoi fare la stessa esatta richiesta PUT più volte e il risultato sarà come se lo avessi eseguito solo una volta.

Descriverò le convenzioni che ritengo più diffuse e più utili:

Quando metti una risorsa su un particolare URL, ciò che accade è che dovrebbe essere salvato su quell'URL o qualcosa del genere.

Quando esegui il POST su una risorsa in un determinato URL, spesso pubblichi una parte correlata di informazioni su quell'URL. Ciò implica che la risorsa all'URL esiste già.

Ad esempio, quando desideri creare un nuovo stream, puoi METTERLO su un URL. Ma quando vuoi POSTARE un messaggio a uno stream esistente, POST l'URL.

Per quanto riguarda la modifica delle proprietà del flusso, puoi farlo con PUT o POST. In pratica, usa "PUT" solo quando l'operazione è idempotente, altrimenti usa POST.

Si noti, tuttavia, che non tutti i browser moderni supportano i verbi HTTP diversi da GET o POST.


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'oggetto 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 oggetto due volte, non ha alcun effetto. Questa è una bella proprietà, quindi userei PUT quando possibile.
  • Puoi aggiornare o creare una risorsa con PUT con lo stesso URL dell'oggetto
  • Con POST è possibile avere 2 richieste contemporaneamente apportando modifiche a un URL e possono aggiornare parti diverse dell'oggetto.

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/<existing_question> HTTP/1.1
Host: www.example.com/

Si noti che quanto segue è un errore:

POST /questions/<new_question> 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é <new_question> non esiste ancora. Devi <new_question> risorsa <new_question> 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/<new_question> HTTP/1.1
Host: www.example.com/

Per sovrascrivere una risorsa esistente:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Ho intenzione di atterrare con il seguente:

PUT fa riferimento a una risorsa, identificata dall'URI. In questo caso, lo stai aggiornando. È la parte dei tre verbi che si riferiscono alle risorse: cancella e ottieni gli altri due.

Il POST è fondamentalmente un messaggio in forma libera, con il suo significato definito "fuori dalla banda". Se il messaggio può essere interpretato come l'aggiunta di una risorsa a una directory, sarebbe OK, ma in pratica è necessario capire il messaggio che si sta inviando (postare) per sapere cosa accadrà con la risorsa.

Poiché PUT, GET e DELETE si riferiscono a una risorsa, sono anche per definizione idempotenti.

POST può eseguire le altre tre funzioni, ma in tal caso la semantica della richiesta andrà persa sugli intermediari come cache e proxy. Questo vale anche per fornire sicurezza sulla risorsa, dal momento che l'URI di un post non indica necessariamente la risorsa a cui si sta applicando (può però).

A PUT non ha bisogno di essere una creazione; il servizio potrebbe errore se la risorsa non è già stata creata, ma in caso contrario aggiornarla. O viceversa - potrebbe creare la risorsa, ma non consentire aggiornamenti. L'unica cosa necessaria per PUT è che punta a una risorsa specifica e il suo carico utile è la rappresentazione di quella risorsa. Un PUT riuscito significa (escludendo l'interferenza) che un GET recuperi la stessa risorsa.

Modifica: Un'altra cosa: un PUT può creare, ma se lo fa, l'ID deve essere un ID naturale - AKA un indirizzo email. In questo modo quando PUT due volte, il secondo put è un aggiornamento del primo. Questo lo rende idempotente .

Se l'ID viene generato (un nuovo ID dipendente, ad esempio), il secondo PUT con lo stesso URL creerà un nuovo record, che viola la regola idempotent. In questo caso il verbo sarebbe POST e il messaggio (non la risorsa) sarebbe quello di creare una risorsa usando i valori definiti in questo messaggio.


il server di origine può creare la risorsa con quell'URI

Quindi usi POST e probabilmente, ma non necessario PUT per la creazione di risorse. Non devi supportare entrambi. Per me POST è perfettamente sufficiente. Quindi è una decisione di progettazione.

Come la tua citazione menzionata, tu usi PUT per la creazione di non ci sono risorse assegnate a un IRI, e tu vuoi comunque creare una risorsa. Ad esempio, in PUT /users/123/passwordgenere sostituisce la vecchia password con una nuova, ma è possibile utilizzarla per creare una password se non esiste già (ad esempio, da utenti appena registrati o ripristinando utenti bannati).


Sembra esserci sempre una certa confusione su quando utilizzare il POST HTTP rispetto al metodo PUT HTTP per i servizi REST. La maggior parte degli sviluppatori proverà ad associare le operazioni CRUD direttamente ai metodi HTTP. Discuterò che questo non è corretto e non si può semplicemente associare i concetti CRUD ai metodi HTTP. Questo è:

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

È vero che R (etrieve) e D (elete) delle operazioni CRUD possono essere mappati direttamente ai metodi HTTP GET e DELETE rispettivamente. Tuttavia, la confusione si trova nelle operazioni C (reate) e U (aggiornamento). In alcuni casi, è possibile utilizzare il PUT per creare mentre in altri casi sarà richiesto un POST. L'ambiguità risiede nella definizione di un metodo PUT HTTP rispetto a un metodo POST HTTP.

In base alle specifiche HTTP 1.1 i metodi GET, HEAD, DELETE e PUT devono essere idempotenti e il metodo POST non è idempotente. Vale a dire che un'operazione è idempotente se può essere eseguita su una risorsa una o più volte e restituire sempre lo stesso stato di quella risorsa. Mentre un'operazione non idempotente può restituire uno stato modificato della risorsa da una richiesta all'altra. Quindi, in un'operazione non idempotente, non vi è alcuna garanzia che si riceverà lo stesso stato di una risorsa.

In base alla suddetta definizione idempotente, il mio modo di utilizzare il metodo PUT HTTP rispetto al metodo POST HTTP per i servizi REST è: Utilizzare il metodo PUT HTTP quando:

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 entrambi i casi, queste operazioni possono essere eseguite più volte con gli stessi risultati. Questa è la risorsa non verrà modificata richiedendo l'operazione più di una volta. Quindi, una vera operazione idempotente. Usa il metodo POST HTTP quando:

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

Non correlare e mappare direttamente le operazioni CRUD ai metodi HTTP per i servizi REST. L'uso di un metodo PUT HTTP rispetto a un metodo POST HTTP dovrebbe essere basato sull'aspetto idempotente di tale operazione. Cioè, se l'operazione è idempotente, quindi utilizzare il metodo HTTP PUT. Se l'operazione non è idempotente, utilizzare il metodo HTTP POST.


Mi piace questo consiglio, dalla definizione di PUT di RFC 2616 :

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'entità inclusa. Quella risorsa potrebbe essere un processo di accettazione dei dati, un gateway per qualche altro protocollo o un'entità separata che accetta annotazioni. Al contrario, l'URI in una richiesta PUT identifica l'entità inclusa nella richiesta: l'agente utente sa quale URI è inteso e il server NON DEVE tentare di applicare la richiesta ad un'altra risorsa.

Questo fa cenno con l'altro consiglio qui, che PUT si applica meglio alle risorse che hanno già un nome e POST è buono per creare un nuovo oggetto sotto una risorsa esistente (e lasciare che sia il nome del server).

Interpreto questo e i requisiti di idempotenza su PUT, nel senso che:

  • POST è buono per creare nuovi oggetti sotto una collezione (e creare non ha bisogno di essere idempotente)
  • PUT è buono per l'aggiornamento di oggetti esistenti (e l'aggiornamento deve essere idempotente)
  • Il POST può anche essere usato per aggiornamenti non identienti di oggetti esistenti (in particolare, cambiando parte di un oggetto senza specificare il tutto - se ci pensate, creare un nuovo membro di una collezione è in realtà un caso speciale di questo tipo di aggiornamento, dal punto di vista della collezione)
  • PUT può essere utilizzato anche per creare se e solo se si consente al client di nominare la risorsa. Ma dal momento che i client REST non sono tenuti a formulare ipotesi sulla struttura dell'URL, questo è meno nello spirito intenzionale delle cose.

In un modo molto semplice sto prendendo l'esempio della timeline di Facebook.

Caso 1: quando pubblichi qualcosa sulla tua timeline, è una nuova entrata. Quindi in questo caso usano il metodo POST perché il metodo POST non è idempotente.

Caso 2: se il tuo amico commenta il tuo post per la prima volta, anche questo creerà una nuova voce nel database in modo tale da utilizzare il metodo POST.

Caso 3: se il tuo amico modifica il suo commento, in questo caso ha un ID commento, quindi aggiornerà un commento esistente anziché creare una nuova voce nel database. Pertanto per questo tipo di operazione utilizzare il metodo PUT perché è idempotente. *

In una singola riga, utilizzare POST per aggiungere una nuova voce nel database e PUT per aggiornare qualcosa nel database.


Entrambi sono usati per la trasmissione dei dati tra client e server, ma ci sono sottili differenze tra loro, che sono:

Analogia:

  • PUT cioè prendi e metti dove era.
  • POST come inviare la posta in posta ufficio.


Nuova risposta (ora che ho capito meglio il REST):

PUT è semplicemente una dichiarazione di quale contenuto il servizio dovrebbe, d'ora in poi, utilizzare per rappresentare la risorsa identificata dal cliente; POST è una dichiarazione di quale contenuto il servizio dovrebbe, d'ora in poi, contenere (possibilmente duplicato) ma spetta al server come identificare quel contenuto.

PUT x(se xidentifica una resource ): "Sostituisci il contenuto della risorsa identificata dal xmio contenuto."

PUT x(se xnon identifica una risorsa): "Crea una nuova risorsa contenente il mio contenuto e utilizzala xper identificarla."

POST x: "Archivia il mio contenuto e forniscimi un identificatore che posso utilizzare per identificare una risorsa (vecchia o nuova) contenente detto contenuto (eventualmente mescolata ad altri contenuti). Detta risorsa dovrebbe essere identica o subordinata a quella che xidentifica." " La risorsa di y è subordinata alla risorsa di x " tipicamente ma non necessariamente implementata facendo di y un sotto percorso di x (es. x = /fooe y = /foo/bar) e modificando la rappresentazione (s) della risorsa x per riflettere l'esistenza di una nuova risorsa, ad es. con un collegamento ipertestuale a yLa risorsa e alcuni metadati. Solo il secondo è davvero essenziale per un buon design, dato che gli URL sono opachi in REST: si suppone che si debba usare hypermedia invece della costruzione URL lato client per attraversare comunque il servizio.

In REST, non esiste una risorsa contenente "contenuto". Mi riferisco come "contenuto" ai dati che il servizio utilizza per rappresentare coerentemente le rappresentazioni. Solitamente consiste in alcune righe correlate in un database o in un file (ad es. Un file immagine). Spetta al servizio convertire il contenuto dell'utente in qualcosa che il servizio può utilizzare, ad esempio la conversione di un carico utile JSON in istruzioni SQL.

Risposta originale (potrebbe essere più facile da leggere) :

PUT /something(se /somethinggià esiste): "Prendi quello che hai /somethinge sostituiscilo con quello che ti do".

PUT /something(se /somethingnon esiste già): "Prendi ciò che ti do e lo metti /something".

POST /something: "Prendi quello che ti do e mettilo ovunque tu voglia /somethingfinché mi dai il suo URL quando hai finito."


Oltre alle differenze suggerite da altri, voglio aggiungerne un'altra.

Nel metodo POST puoi inviare i parametri del corpo inform-data

Nel metodo PUT devi inviare i parametri del corpo inx-www-form-urlencoded

Intestazione Content-Type:application/x-www-form-urlencoded

In base a questo, non è possibile inviare file o dati multiparte nel metodo PUT

MODIFICARE

Il tipo di contenuto "application / x-www-form-urlencoded" è inefficiente per l'invio di grandi quantità di dati binari o di testo contenenti caratteri non ASCII. Il tipo di contenuto "multipart / form-data" deve essere utilizzato per inviare moduli che contengono file, dati non ASCII e dati binari.

Il che significa se devi presentare

file, dati non ASCII e dati binari

dovresti usare il metodo POST


Ecco una semplice regola:

PUT a un URL dovrebbe essere usato per aggiornare o creare la risorsa che può essere localizzata in quell'URL.

Il POST di un URL deve essere utilizzato per aggiornare o creare una risorsa che si trova in qualche altro URL ("subordinato") o non localizzabile via HTTP.


Se hai familiarità con le operazioni del database, ci sono

  1. Selezionare
  2. Inserire
  3. Aggiornare
  4. Elimina
  5. Unisci (aggiorna se già esistente, altrimenti inserisci)

Io uso PUTper Unisci e aggiorno le operazioni come e uso POSTper Inserimenti.


Questa sarebbe una versione della risposta selezionata usando jQuery .

// Post to the provided URL with the specified parameters.
function post(path, parameters) {
    var form = $('<form></form>');

    form.attr("method", "post");
    form.attr("action", path);

    $.each(parameters, function(key, value) {
        var field = $('<input></input>');

        field.attr("type", "hidden");
        field.attr("name", key);
        field.attr("value", value);

        form.append(field);
    });

    // The form needs to be a part of the document in
    // order for us to be able to submit it.
    $(document.body).append(form);
    form.submit();
}




http rest post put