Vraag PUT versus POST in REST


Volgens de HTTP / 1.1-specificatie:

De POST methode wordt gebruikt om te verzoeken dat de oorspronkelijke server de in de aanvraag ingesloten entiteit accepteert als een nieuwe ondergeschikte van de door de Request-URI in de Request-Line

Met andere woorden, POST is gewend aan creëren.

De PUT methode vraagt ​​dat de ingesloten entiteit wordt opgeslagen onder de geleverde Request-URI. Als het Request-URI verwijst naar een reeds bestaande bron, de bijgevoegde entiteit MOET worden beschouwd als een aangepaste versie van degene die zich op de oorspronkelijke server bevindt. Als het Request-URI wijst niet naar een bestaande bron en die URI kan door de verzoekende user-agent als een nieuwe resource worden gedefinieerd, de origin-server kan de resource met die URI maken. "

Dat is, PUT is gewend aan maken of updaten.

Dus, welke moet worden gebruikt om een ​​resource te maken? Of moet je beide ondersteunen?


4456
2018-03-10 14:25


oorsprong


antwoorden:


Algemeen: 

Zowel PUT als POST kunnen worden gebruikt voor het maken.

Je moet vragen "waar voer je de actie naar toe?" om te onderscheiden wat u zou moeten gebruiken. Laten we aannemen dat je een API ontwerpt voor het stellen van vragen. Als u POST wilt gebruiken, doet u dat op een lijst met vragen. Als je PUT wilt gebruiken, zou je dat met een bepaalde vraag doen.

Geweldig dat beide kunnen worden gebruikt, dus welke moet ik gebruiken in mijn RESTful ontwerp:

U hoeft PUT en POST niet te ondersteunen.

Welke wordt gebruikt, wordt aan u overgelaten. Maar vergeet niet om de juiste te gebruiken, afhankelijk van het object waarnaar u verwijst in het verzoek.

Enkele overwegingen:

  • Noemt u uw URL-objecten die u expliciet maakt, of laat u de server beslissen? Als je ze een naam geeft, gebruik dan PUT. Als u de server laat beslissen, gebruikt u POST.
  • PUT is idempotent, dus als je een object twee keer PUTT, heeft het geen effect. Dit is een mooie eigenschap, dus ik zou PUT indien mogelijk gebruiken.
  • U kunt een resource bijwerken of maken met PUT met dezelfde object-URL
  • Met POST kunt u twee verzoeken tegelijk invoeren en wijzigingen in een URL aanbrengen, en kunnen ze verschillende delen van het object bijwerken.

Een voorbeeld:

Ik schreef het volgende als onderdeel van een ander antwoord op SO met betrekking tot dit:

POST:

Gebruikt om een ​​hulpmiddel te wijzigen en bij te werken

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

Merk op dat het volgende een fout is:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

Als de URL nog niet is aangemaakt, jij   zou POST niet moeten gebruiken om het te creëren   terwijl u de naam opgeeft. Dit zou   resulteren in een 'resource not found' fout   omdat <new_question> bestaat niet   nog. Je moet de <new_question>   bron eerst op de server.

Je zou echter wel zoiets kunnen doen   dit om bronnen te maken met behulp van POST:

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

Merk op dat in dit geval de bron   naam is niet gespecificeerd, de nieuwe objecten   URL-pad zou aan u worden geretourneerd.

LEGGEN: 

Wordt gebruikt om een ​​resource te maken, of   overschrijf het. Terwijl u de. Opgeeft   middelen nieuwe URL.

Voor een nieuwe bron:

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

Om een ​​bestaande bron te overschrijven:

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

3480
2018-03-10 14:29



Je kunt beweringen op het web vinden die zeggen

Geen van beide heeft helemaal gelijk.


Beter is om te kiezen tussen PUT en POST op basis van idempotentie van de actie.

LEGGEN impliceert het plaatsen van een hulpbron - volledig vervangen wat beschikbaar is op de gegeven URL met een ander ding. Per definitie is een PUT idempotent. Doe het zo vaak als je wilt, en het resultaat is hetzelfde. x=5 is idempotent. U kunt een resource PUTTEN, ongeacht of deze al bestond, of niet (bijvoorbeeld om te maken of om bij te werken)!

POST werkt een resource bij, voegt een hulpbron toe of veroorzaakt een wijziging. Een POST is niet idempotent, zoals dat x++ is niet idempotent.


Met dit argument is PUT bedoeld om te maken wanneer u de URL kent van het item dat u gaat maken. POST kan worden gebruikt om te maken wanneer u de URL van de "fabriek" of manager kent voor de categorie dingen die u wilt maken.

zo:

POST /expense-report

of:

PUT  /expense-report/10929

1878
2018-04-22 14:55



  • POST naar een URL maakt een onderliggende bron op een server gedefinieerd URL.
  • LEGGEN naar een URL maakt / vervangt de bron in zijn geheel op de klant gedefinieerd URL.
  • PATCH naar een URL updates een deel van de bron bij die door de klant gedefinieerde URL.

De relevante specificatie voor PUT en POST is RFC 2616 §9.5ff.

POST maakt een onderliggende resource, dus POST naar /items creëert bronnen die onder de /items bron. Bijv. /items/1. Als u hetzelfde postpakket twee keer verzendt, worden twee bronnen gemaakt.

LEGGEN is voor het maken of vervangen van een resource op a URL bekend bij de klant.

daarom: LEGGEN is alleen een kandidaat voor CREATE als de client de URL al kent voordat de resource is gemaakt. Bijv. /blogs/nigel/entry/when_to_use_post_vs_put omdat de titel wordt gebruikt als de bronsleutel

LEGGEN vervangt de bron bij de bekende URL als deze al bestaat, dus hetzelfde verzoek twee keer verzenden heeft geen effect. Met andere woorden, oproepen naar PUT zijn idempotent.

De RFC leest als volgt:

Het fundamentele verschil tussen de POST- en PUT-verzoeken wordt weerspiegeld in de verschillende betekenis van de Request-URI. De URI in een POST-aanvraag identificeert de resource die de ingesloten entiteit zal afhandelen. Die bron kan een gegevensacceptatieproces zijn, een toegangspoort tot een ander protocol of een afzonderlijke entiteit die annotaties accepteert. In tegenstelling hiermee identificeert de URI in een PUT-aanvraag de entiteit die bij de aanvraag is gevoegd - de user-agent weet welke URI is bedoeld en de server MOET NIET proberen de aanvraag toe te passen op een andere resource. Als de server wenst dat het verzoek wordt toegepast op een andere URI,

Notitie: PUT is meestal gebruikt om middelen bij te werken (door ze in hun geheel te vervangen), maar recent is er beweging in het gebruik van PATCH voor het bijwerken van bestaande bronnen, omdat PUT aangeeft dat het de hele bron vervangt. RFC 5789.


562
2018-04-07 05:52



Overzicht:

Maken:

Kan op de volgende manier worden uitgevoerd met zowel PUT of POST:

LEGGEN

Maakt DE nieuwe bron met newResourceId als de identifier, onder de / resources URI, of verzameling.

PUT /resources/<newResourceId> HTTP/1.1 

POST

Maakt EEN nieuwe bron onder de / resources URI, of verzameling. Meestal wordt de ID door de server geretourneerd.

POST /resources HTTP/1.1

Bijwerken:

Kan enkel en alleen worden uitgevoerd met PUT op de volgende manier:

LEGGEN

Werkt de bron bij met existingResourceId als de identifier, onder de / resources URI, of verzameling.

PUT /resources/<existingResourceId> HTTP/1.1

Uitleg:

Bij het omgaan met REST en URI als algemeen, hebt u algemeen op de links en specifiek op de rechts. De generics worden meestal genoemd verzamelingen en hoe meer specifiek items kunnen worden gebeld hulpbron. Merk op dat a hulpbron kan een bevatten verzameling.

Voorbeelden:

<- generiek - specifiek ->

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

Wanneer je POST gebruikt, ben je dat altijd verwijzen naar een verzameling, dus wanneer je zegt:

POST /users HTTP/1.1

u plaatst een nieuwe gebruiker in de gebruikers  verzameling.

Als je doorgaat en zoiets probeert als dit:

POST /users/john HTTP/1.1

het zal werken, maar semantisch zeg je dat je een bron wilt toevoegen aan de John  verzameling onder de gebruikers  verzameling.

Als u PUT gebruikt, verwijst u naar a hulpbron of een enkel item, mogelijk binnen een verzameling. Dus als je zegt:

PUT /users/john HTTP/1.1

u vertelt aan de serverupdate, of creëer als het niet bestaat, de John  hulpbron onder de gebruikers  verzameling.

spec:

Laat me enkele belangrijke delen van de specificatie benadrukken:

POST

De POST methode wordt gebruikt om de oorsprongserver op te vragen aanvaarden de entiteit ingesloten in het verzoek als een nieuwe ondergeschikt van de resource geïdentificeerd door de Request-URI in de Request-Line

Vandaar, creëert een nieuw hulpbron op een verzameling.

LEGGEN

De LEGGEN methode vraagt ​​om de ingesloten entiteit opgeslagen onder de geleverde Request-URI. Als de aanvraag-URI verwijst naar een al bestaand bron, de ingesloten entiteit MOET worden beschouwd als een aangepaste versie van degene die op de oorspronkelijke server verblijft. Als de Request-URI dat doet niet verwijzen naar een bestaand bron, en die URI is in staat van worden gedefinieerd als een nieuwe hulpbron door de aanvragende user-agent kan de origin-server dat doen creëren de bron met die URI. "

Dus maak of update op basis van het bestaan ​​van de hulpbron.

Referentie:


165
2017-08-14 22:47



Ik wil graag mijn "pragmatische" advies toevoegen. Gebruik PUT als u de "id" kent waarmee het object dat u opslaat, kan worden opgehaald. Het gebruik van PUT zal niet al te goed werken als u, bijvoorbeeld, een door een database gegenereerde id nodig heeft om voor u teruggestuurd te worden om toekomstige opzoekingen of updates te doen.

Dus: om een ​​bestaande gebruiker op te slaan, of een waar de client de ID genereert en is geverifieerd dat de ID uniek is:

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

Gebruik anders POST om het object eerst te maken en PUT om het object bij te werken:

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

156
2018-01-15 19:59



POST betekent "maak nieuw" zoals in "Hier is de invoer voor het maken van een gebruiker, maak deze voor mij".

PUT betekent "invoegen, vervangen als deze al bestaat" zoals in "Hier zijn de gegevens voor gebruiker 5".

U POST naar example.com/users omdat u de URL van de gebruiker nog niet kent, u wilt dat de server deze maakt.

Je hebt PUT naar example.com/users/id gezet omdat je een wilt vervangen / maken specifiek gebruiker.

POSTing tweemaal met dezelfde data betekent twee identieke gebruikers creëren met verschillende ID's. PUTing tweemaal met dezelfde data creëert de gebruiker de eerste en update hem voor de tweede keer naar dezelfde staat (geen wijzigingen). Omdat je na een PUT met dezelfde staat eindigt, ongeacht hoe vaak je het doet, wordt er gezegd dat elke keer "even krachtig" is - idempotent. Dit is handig voor het automatisch opnieuw proberen van aanvragen. Nooit meer 'weet je zeker dat je opnieuw wilt verzenden' wanneer je op de terugknop van de browser drukt.

Een algemeen advies is om POST te gebruiken wanneer u de server nodig heeft om controle te hebben over het genereren van uw bronnen. Gebruik anders PUT. Geef de voorkeur aan PUT over POST.


145
2017-10-23 14:27



Gebruik POST om te maken en PUT om bij te werken. Dat is hoe Ruby on Rails het doet.

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

105
2018-03-10 14:28



REST is a heel hoog niveau concept. In feite wordt er helemaal geen HTTP vermeld!

Als u twijfelt over het implementeren van REST in HTTP, kunt u altijd de Atom Publication Protocol (AtomPub) specificatie. AtomPub is een standaard voor het schrijven van RESTful webservices met HTTP die is ontwikkeld door veel HTTP- en REST-armaturen, met een beetje input van Roy Fielding, de uitvinder van REST en (mede) uitvinder van HTTP zelf.

Misschien kunt u AtomPub zelfs rechtstreeks gebruiken. Hoewel het uit de blogcommunity kwam, is het op geen enkele manier beperkt tot bloggen: het is een generiek protocol voor RESTfully interactie met willekeurige (geneste) collecties van willekeurige bronnen via HTTP. Als u uw toepassing kunt weergeven als een geneste verzameling bronnen, kunt u AtomPub gebruiken en hoeft u zich geen zorgen te maken over het gebruik van PUT of POST, welke HTTP-statuscodes moeten worden geretourneerd en al die details.

Dit is wat AtomPub te zeggen heeft over het creëren van bronnen (paragraaf 9.2):

Om leden aan een verzameling toe te voegen, verzenden clients POST-aanvragen naar de URI van de verzameling.


58
2018-03-10 15:27