PUNE-vs POST în RESTUL
Potrivit HTTP/1.1 Spec.:
POST
metodă este folosită pentru a solicita ca server de origine accepta entitate închisă în cerere ca un nou subordonat resurse identificate prin Cererea-URI " în " Cerere-Line`
Cu alte cuvinte, "POST" este folosit pentru a crea.
"PUNE" metoda solicită ca entitate închisă fi stocate sub furnizate Cererea-URI
. Dacă Cererea-URI se referă la o resursă existentă, închise entitate ar TREBUI să fie considerat ca o versiune modificata de cel care are reședința pe serverul de origine. Dacă Cererea-URI
nu indică o resursă existentă, și asta-URI poate fi definit ca o nouă resursă de a solicita user agent, originea server poate crea resurse cu asta URI."
Că este, "a PUS" este folosit pentru a a crea sau actualiza.
Deci, care ar trebui să fie folosit pentru a crea o resursă? Sau o nevoie de a sprijini atât?
În general:
Amândoi și POST pot fi utilizate pentru crearea.
Trebuie sa intrebi "ce realizează acțiunea de a?" de a distinge ceea ce ar trebui să fie folosind. Las's presupunem tine're proiectarea unui API pentru a pune întrebări. Dacă doriți să utilizați POST, atunci v-ar face asta la o listă de întrebări. Dacă doriți să utilizați PUNE apoi te-ar face asta la o anumită întrebare.
Mare ambele pot fi folosite, deci, care ar trebui să îl folosesc în Odihnitor design:
Nu aveți nevoie de sprijin, cât și de POST.
Care este folosit este lăsat până la tine. Dar doar amintiți-vă să utilizați una corectă, în funcție de ce obiect care faceți referire în cerere.
Unele considerații:
Exemplu:
Am scris următoarele, ca parte a un alt răspuns pe ATÂT cu privire la acest:
Puteți găsi afirmații pe web, care spune
Nici nu este destul de dreapta.
Mai bine este de a alege între a PUS și POST bazat pe idempotence de acțiune.
PUNE presupune punerea unei resurse - înlocuirea complet ceea ce este disponibil la URL-ul dat cu un alt lucru. Prin definiție, o PUNE este idempotent. Face ca de multe ori doriți, și rezultatul este același.
x=5
este idempotent. Puteți PUNE o resursă dacă anterior exista, sau nu (de exemplu, pentru a Crea sau pentru a Actualiza)!POST actualizări de o resursă, adaugă o filială de resurse, sau de a produce o schimbare. Un POST nu este idempotent, în felul în care
x++
nu este idempotent.Prin acest argument, este PUS pentru crearea când știți URL-ul de lucru pe care îl va crea. POST poate fi folosit pentru a crea, atunci când știți URL-ul de "fabrica" sau manager pentru categoria de lucruri pe care doriți să creați.
deci:
sau:
Specificația relevantă pentru a PUNE și POST este RFC 2616 §9.5 ff.
POST creează o resursă copil, astfel încât POSTUL să
/elemente creează o resurse care trăiește sub
/elementede resurse. De exemplu.
/articole/1`. Trimiterea la același post de pachete de două ori va crea două resurse.PUNE este pentru crearea sau înlocuirea unei resurse la un URL-ul cunoscut de către client.
Prin urmare: PUNE este doar un candidat pentru a CREA în cazul în care clientul știe deja url-ul înainte de resurse este creat. De exemplu.
/bloguri/nigel/de intrare/when_to_use_post_vs_put
ca titlul este folosit ca resursă cheiePUNE înlocuiește resurse la cunoscut url-ul, dacă acesta există deja, așa că trimiterea aceeași cerere de două ori nu are nici un efect. Cu alte cuvinte, apeluri pentru a PUNE sunt idempotent.
RFC citește astfel:
Notă: - a PUS a fost folosit mai ales pentru a actualiza resursele (prin înlocuirea lor în entireties), dar, recent, există o mișcare spre utilizarea de PATCH-uri pentru actualizarea resurselor existente, astfel cum se specifică faptul că se înlocuiește întreaga resursă. RFC 5789.
Actualizare 2018: nu Există un caz care poate fi făcut pentru a evita PUS. Vezi "RESTUL, fără a PUNE"
preluat din REST API Design - Resurse de Modelare de Prakash Subramaniam de Thoughtworks
Aceasta obligă API pentru a evita starea de tranziție probleme cu mai mulți clienți actualizarea unei singure resurse, și se potrivește mai bine cu evenimentul de aprovizionare și CQRS. Atunci când munca se face asincron, Postarea de transformare și de așteptare pentru ca acesta să fie aplicate pare adecvat.
Rezumat:
Crea:
Poate fi realizată atât cu PUI sau POSTA în felul următor:
Update:
Poate **** a fi efectuat cu PUNE în felul următor:
Explicatie:
Atunci când se ocupă cu RESTUL și URI ca general, ai generic pe left și specifice pe right. La generice sunt de obicei numite colecții și mai mult specifice elemente poate fi numit resurse. Rețineți că un resurse poate conține un colectarea.
Atunci când utilizați POST esti mereu referindu-se la o colectarea, astfel încât ori de câte ori ai spus:
postați un utilizator nou la users colectarea.
Dacă te duci pe și să încerce ceva de genul asta:
acesta va lucra, dar semantic spuneți că doriți să adăugați o resursă pentru john colectarea sub users colectarea.
Odată ce sunteți folosind PUNE referire la o resurse sau singur element, eventual, în interiorul unui colectarea. Deci, atunci când spui:
spui la serverul de actualizare, sau pentru a crea, dacă nu't există, john resurse sub users colectarea.
Spec:
Permiteți-mi să evidențiez unele părți importante ale spec.:
POST
Prin urmare, creează un nou resurse pe colectarea.
PUS
Prin urmare, de a crea sau actualiza bazează pe existența resurse.
Referință:
Am'd dori să adăugați meu "pragmatică" sfaturi. Utilizarea PUNE atunci când știi "id" prin care obiectul sunteți de economisire pot fi recuperate. Folosind PUS câștigat't merge prea bine dacă aveți nevoie de, să zicem, o bază de date generate de identitate pentru a fi returnate pentru tine să faci în viitor căutări sau actualizări.
Deci: Pentru a salva un utilizator existent, sau una în care clientul generează id-ul și it's-a verificat că id-ul este unic:
POST inseamna "a crea noi" la fel ca în "Aici este de intrare pentru a crea un utilizator, de a crea pentru mine".
PUNE-înseamnă "introduce, înlocuiți dacă există deja" la fel ca în "Aici sunt datele de utilizator de 5".
Tine POST pentru a example.com/users din moment ce tu nu't știu URL-ul utilizatorului, totuși, doriți ca serverul să-l creeze.
Ai PUS de a example.com/users/id când doriți să înlocuiți/crea un specifice utilizator.
Postarea de două ori cu aceleași date înseamnă a crea două identice utilizatorii cu id-uri diferite. Punand de două ori cu aceleași date creează utilizatorul primul și actualizări-l la același stat a doua oară (fără modificări). Când te trezești cu aceeași stare după o PUNE, indiferent de câte ori a efectua, este declarat a fi "la fel de puternic" de fiecare dată - idempotent. Acest lucru este util pentru a reîncerca automat cereri. Nu mai 'sunteți sigur că doriți să-l retrimiteți' atunci când apăsați butonul din spate de pe browser-ul.
Un sfat general este de a utiliza POSTA atunci când ai nevoie de server pentru a fi în controlul de generare URL de resurse. Utilizarea PUNE altfel. Prefera PUS pe POST.
Utilizarea POST pentru a crea, și de a PUNE pentru a actualiza. Ca's cum Ruby on Rails este de a face, oricum.
Ambele sunt folosite pentru transmisia de date între client la server, dar există diferențe subtile între ele, care sunt:
Analogie:
Social Media/Rețea Analogie:
RESTUL este foarte mare la nivel de concept. În fapt, aceasta nu't chiar menționez HTTP la toate!
Dacă aveți îndoieli despre cum să pună în aplicare RESTUL în HTTP, puteți lua întotdeauna o privire la [Atom Publicarea Protocolului (AtomPub)][1] caietul de sarcini. AtomPub este un standard pentru scrierea Odihnitor webservices cu HTTP, care a fost dezvoltat de către mulți HTTP și RESTUL corpuri de iluminat, cu unele intrare de Roy Fielding, inventatorul de ODIHNĂ și (co-)inventatorul HTTP el însuși.
În fapt, s-ar putea chiar să fie capabil de a utiliza AtomPub direct. În timp ce a ieșit din comunitate blogging-ul, este în nici un fel limitată la blogging: ea este un protocol generic pentru Odihnitor interacționează cu arbitrare (imbricate) colecții de arbitrare resurse prin intermediul HTTP. Dacă poți să-ți reprezinți aplicație ca un imbricate colecție de resurse, atunci puteți folosi doar AtomPub și nu vă faceți griji cu privire la posibilitatea de a folosi PUI sau de POST, ce Coduri de Stare HTTP pentru a reveni și toate acele detalii.
Aceasta este ceea ce AtomPub are de spus despre crearea de resurse (secțiunea 9.2):
Decizia de a folosi PUS sau POST pentru a crea o resursă pe un server cu un HTTP + REST API este în funcție de cine deține structura de URL-ul. Având știu client, sau de a participa la definirea, URL-ul struct este un inutilă de cuplare înrudită cu cuplaje nedorite care au apărut de la SOA. Evadarea tipuri de cuplaje este motivul RESTUL este atât de popular. Prin urmare, buna metoda de a utiliza este de POST. Există și excepții de la această regulă și ele apar atunci când clientul dorește să-și păstreze controlul asupra localizarea structurii de resursele pe care le desfășoară. Acest lucru este rar și probabil înseamnă că ceva este greșit. În acest moment, unii oameni vor argumenta că, dacă Odihnitor-URL's au folosit, clientul nu știe URL-ul resursei și, prin urmare, o PUNE este acceptabil. După toate, acest lucru este de ce canonice, normalizat, Ruby on Rails, Django Url-urile sunt importante, uita-te la Twitter API ... bla bla bla. Acei oameni trebuie să înțeleagă nu există nici un astfel de lucru ca un Odihnitor-URL-ul și Roy Fielding însuși afirmă că:
Îmi place acest sfat, de RFC 2616's definiție a PUS:
Acest jibes cu alte sfaturi aici, care este cel mai bine aplicat la resurse care au deja un nume, iar POSTUL este bun pentru a crea un nou obiect sub o resursă existentă (și lasă server de nume).
Eu interpretez asta, și idempotency cerințele pe PUNE, înseamnă că:
Pe scurt:
PUNE este idempotent, în cazul în care resursa de stat va fi aceeași în cazul în care aceeași operație este executată o singură dată sau de mai multe ori.
POST este non-idempotent, în cazul în care resursa de stat poate deveni diferit dacă operația este executată de mai multe ori față de a executa o singură dată.
Analogie cu interogare a bazei de date
PUNE Vă puteți gândi similar cu "ACTUALIZARE STUDENT SET adresa = "abc" în cazul în care id="123";
POST Vă puteți gândi ceva de genul "INSERT INTO STUDENT(nume, adresa) VALUES ("abc", "xyzzz");
Id-ul de Student este generat automat.
Cu PUNE, dacă interogarea este executată de mai multe ori sau o singură dată, ELEVUL tabelul de stat rămâne aceeași.
În caz de POST, dacă aceeași interogare este executat de mai multe ori, apoi de mai multe înregistrări de studenți create în baza de date și baza de date modificările de stat pe fiecare execuție a unui "INTRODUCE" de interogare.
NOTĂ: PUNE are nevoie de o resursă locație (deja-resurse) pe care de actualizare trebuie să se întâmple, întrucât POSTUL nu't nevoie de asta. Prin urmare, intuitiv POST este destinat pentru crearea unei noi resurse, întrucât PUNE este necesar pentru actualizarea deja existente de resurse.
Unii pot veni cu actualizări pot fi efectuate cu POST. Nu există nici o regulă greu pe care să o folosiți pentru actualizări sau pe care să o folosiți pentru a crea. Din nou, acestea sunt convenții, și intuitiv am'm înclinată cu cele menționate mai sus raționament și urmați-l.
POST este ca si cum ai posta o scrisoare de la o cutie poștală sau de a posta un e-mail la un e-mail coadă. Este ca și când ai pune un obiect într-o gaura sau un loc pe un raft (are o adresă cunoscută).
Cu POST,'re posta la adresa de COADĂ sau de COLECTARE. Cu PUNE, te're punerea la adresa articolului.
PUNE este idempotent. Puteți trimite solicitarea de 100 de ori și nu va mai conta. POST nu este idempotent. Dacă trimiteți cererea de 100 de ori, te'll obține 100 de e-mailuri sau 100 de scrisori în cutia dvs. poștală.
O regulă generală: dacă știi id-ul sau numele de element, utilizați PUS. Daca vrei id-ul sau numele de elementul care urmează să fie atribuite de către partea primitoare, utilizați POST.
Nou răspuns (acum, că am înțeles bine):
Este doar o declarație de la ce conținut de servicii ar trebui, de acum, utilizați pentru a face reprezentări de resurse identificate de către client; POST este o declarație a ceea ce conținutul de servicii ar trebui, de acum înainte, conțin (eventual duplicat), dar's up la server cum de a identifica acel conținut.
PUNE x` (dacă " x "identifică o resurse): "Înlocui conținutul de resursa identificată prin" x " cu conținutul meu."
PUNE x` (daca " x "nu a identifica o resursă): "a Crea o nouă resursă care conține conținutul meu și de a folosi" x " să-l identifice."
POST x
: "Magazin conținutul meu și dă-mi un identificator pe care le pot folosi pentru a identifica o resursă (vechi sau nou) care conțin conținut (eventual amestecat cu alte tipuri de conținut). A spus resource ar trebui să fie identice sau subordonat care " x " identifică." "_y_'s resurse este subordonat _x_'s resurse" este de obicei dar nu neapărat puse în aplicare printr-_y_ o subpath de _x_ (de exemplu, _x_ =
/fooși _y_ =
/foo/bar`) și modificarea reprezentării(e) de x's resurse pentru a reflecta existența unei noi resurse, de exemplu cu un hyperlink la y's resurse și unele metadate. Numai acesta din urmă este într-adevăr esențială pentru un design bun, ca Url-uri sunt opace in REST ... ai're ar trebui să utilizare hypermedia în loc de client-side URL-ul de construcție pentru a traversa serviciu oricum.In REST, nu's nici un astfel de lucru ca o resursă care conține "content". Ma refer ca "content" de date care serviciul utilizează pentru a face declarații în mod constant. Acesta constă de obicei în câteva rânduri legate într-o bază de date sau un fișier (de exemplu, un fișier de imagine). L's până la serviciu pentru a converti utilizator's de conținut în ceva serviciului poate folosi, de exemplu, conversia un JSON utilă în declarații SQL.
Original răspuns (ar putea fi mai ușor de citit):
PUNE /ceva (dacă/ceva există deja): "Ia tot ce ai la
/ceva și înlocuiți-l cu ce-ți dau."PUNE /ceva (dacă/ceva nu există deja): "Ia ce-ți dau și pune-l la
/ceva`."POST /ceva
: "Ia ce-ți dau și pune-l oriunde doriți în
/ceva atâta timp cât dă-mi URL-ul său, atunci când te're făcut."Răspuns Scurt:
Regulă simplă de degetul mare: Foloseste POST pentru a crea, utiliza PUNE la actualizare.
Timp De Răspuns:
POST:
PUNE:
Mai Răspunde:
Să înțelegem că avem nevoie pentru a PUNE întrebarea de ce a fost necesar, ce probleme PUNE încerca să rezolve acest POST n't.
Din RESTUL de arhitectura's punct de vedere nu este nici unul care contează. Am fi putut trăi fără a PUNE cât mai bine. Dar de la un client developer's punctul de vedere al lui/ei de viață mult mai simplu.
Înainte de a PUNE, clientii n't direct știți URL-ul pe care serverul a generat sau, dacă nu a generat nicio sau dacă datele să fie trimise la server este deja actualizat sau nu. PUNE ușurat dezvoltator de toate aceste batai de cap. PUNE este idempotent, PUNE ocupă de condițiile de rasă, și a PUS permite clientul alege URL-ul.
Ruby on Rails 4.0 va utiliza 'PATCH' metoda în loc de a PUNE de-a face parțială actualizări.
RFC 5789 spune despre PATCH-uri (din 1995):
"C Șine: PATCH este noul primar metoda HTTP pentru updates" explică ea.
Cu riscul de a se amintească ceea ce a fost deja spus, se pare important să ne amintim că PUNE presupune că clientul controale ce URL este de gând să sfârșesc prin a fi, atunci când se creează o resursă. Deci, o parte din alegerea între PUNE și POST este de gând să fie despre cât de mult poți să ai încredere în client pentru a oferi corect, normalizat URL care sunt coerente cu orice URL-ul dvs. de sistem este.
Când poți't pe deplin încredere în client pentru a face dreptul de lucru, ar fi mai adecvat pentru a utiliza POST pentru a crea un nou element și apoi trimite URL-ul înapoi la client în răspuns.
Într-un mod foarte simplu am'm a lua exemplu de la Facebook timeline.
Cazul 1: Cand postezi ceva pe timeline-ul, l's de o nouă intrare. Deci, în acest caz se utilizează metoda POST, deoarece POSTUL metoda este non-idempotent.
Cazul 2: Dacă prietenul tău comentariu privind postarea dvs. prima dată, care, de asemenea, va crea o nouă intrare în baza de date astfel încât POST de metoda utilizată.
Cazul 3: Dacă prietenul tău editează comentariul său, în acest caz, au avut un comentariu id-ul, astfel încât acestea vor actualizați o înregistrare existentă comentariu în loc de a crea o nouă intrare în baza de date. Prin urmare, pentru acest tip de operațiune folosi PUS metodă deoarece este idempotent.*
Într-o singură linie, utilizați POST pentru a adăuga o nouă intrare în baza de date și PUNE la **** update ceva în baza de date.
Cel mai important aspect este fiabilitate. Dacă un POST mesajul se pierde starea sistemului este nedefinit. Recuperare automată este imposibil. Pentru a PUNE mesaje, statul nu este definită numai până la primul succes încercați din nou.
De exemplu, aceasta nu poate fi o idee bună pentru a crea tranzacțiile cu carduri de credit cu POST.
Dacă se întâmplă să aveți auto generate URI's de pe resource puteți utiliza în continuare PUS prin trecerea unui generate URI (arătând spre un gol de resurse) pentru client.
Alte considerente:
În plus față de diferențele sugerat de către alții, vreau să mai adaug unul.
În POST metodă puteți trimite corpul params în formă de date
În PUNE metoda trebuie să trimită corpul params în
x-www-form-urlencoded
Antet
Content-Type:application/x-www-form-urlencoded
În funcție de acest lucru, nu puteți trimite fișiere sau mai multe date in PUNE metoda
EDIT
Ceea ce înseamnă că dacă ai să prezinte
ar trebui să utilizați POST metoda