HTTP PUT vs. POST

Use PUT when modifying a resource that is already a part of resource collection. Use POST when adding a child resource to the collection.

When designing REST APIs, this has been observed that many people struggle to choose between HTTP PUT or POST methods due to their seemingly similar objectives – both involve sending data to a server. However, understanding the differences between HTTP PUT and POST is crucial for their correct usage.

Though, RFC 2616 has been very clear in differentiating between the two – yet complex wordings are a source of confusion for many of us. Let’s try to solve the puzzle of when to use PUT or POST methods.

1. Difference between PUT and POST

Let us start with the distinctions between these two HTTP methods to provide a comprehensive understanding.

HTTP PUT
HTTP POST
The HTTP specification clearly mentions that PUT method requests for the attached entity (in the request body) to be stored on the server that hosts the supplied Request-URI.

If the Request-URI refers to an already existing resource – an update operation will happen, otherwise create operation should happen if Request-URI is a valid resource URI (assuming the client is allowed to determine the resource identifier).
PUT /questions/{question-id}
The POST method requests that the origin server accept the entity attached in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

It essentially means that POST Request-URI should be of a collection URI.
POST /questions
PUT method is idempotent. So if we retry a request multiple times, that should be equivalent to a single request invocation.
POST is NOT idempotent. So if we retry the request N times, we will end up having N resources with N different URIs created on the server.
Use PUT when we want to modify a singular resource that is already a part of resource collection. PUT replaces the resource in its entirety. Use PATCH if the request updates part of the resource.
Use POST when you want to add a child resource under resources collection.
Though PUT is idempotent, we should not cache its response.
Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields.

However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
Generally, in practice, use PUT for UPDATE operations.
Always use POST for CREATE operations.

2. Choosing Between PUT and POST

To decide between HTTP PUT and POST, it’s essential to consider your specific use case:

  • Use HTTP PUT when you want to update or create a specific resource at a known URI in an idempotent manner. This is suitable for scenarios where you have full control over resource replacement.
  • Use HTTP POST when you need to submit data for processing, create new resources without specifying a URI, or perform non-idempotent operations.

3. PUT vs. POST with Example

Let’s say we are designing a network application. Let’s list down a few URIs and their purpose to get a better understanding of when to use POST and when to use PUT operations.

GET 	/device-management/devices       : Get all devices
POST 	/device-management/devices       : Create a new device

GET 	/device-management/devices/{id}   : Get the device information identified by "id"
PUT 	/device-management/devices/{id}   : Update the device information identified by "id"
DELETE	/device-management/devices/{id}   : Delete device by "id"

Follow similar URI design practices for other resources as well.

4. Summary

Understanding the distinctions between HTTP PUT and POST and their respective use cases is pivotal to creating well-designed REST APIs. By following the suggestions discussed above, we can design robust APIs that are easy to deliver and maintain.

Happy Learning !!

Comments

Subscribe
Notify of
guest
36 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Jack

The distinction for the API definition makes complete sense. I was glad to finally understand why there were more than one method. Thank you for the explanation.

Abhy

I have one field added to HR Cloud for al employees. I want to update that field to a value, say, “False”. How to achieve via a Put query for that ?

Matt

You should do that through a HTTP PATCH.

Dinendran S

I was doing an Upload test for 5G networks,
My PUT tasks yielded more throughput(almost double) than POST tasks.
Any idea why the data speed of uploading is influenced by PUT and POST differently?

Any help is highly appreciable 🙂

BR//
Dinu

Eric Carmody

What should be the typical/appropriate HTTP status code returned when attempting to PUT when no record exists. Vice versa, what status to return when attempting a POST on an existing record?

Manan Kapadia

Hey Eric,

You can send status 404 (Not Found) if an entry does not exist.

For POST on an existing record, i think you can use a 401 Bad Request, I am not sure about this.

Do look at this article.

Bob Bob

According to https://www.ietf.org/rfc/rfc2616.txt Section 9.4:

“If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.”

“… can create the resource …” implies that it’s up to you to either create the resource or not

masber

the rfc link points to a obsolete resource. This is the proposed one for http 1.1 https://tools.ietf.org/html/rfc7231

the text says:
The target resource in a POST request is intended to handle the enclosed representation according to the resource’s own semantics

to me this means that POST is more flexible than PUT, put should only create a new entity if doesn’t exists or update existing one. POST can create a new entity or do anything else.

Shweta goyal

Why we need post if put did create and update both?

Rith Lim

Good question. I believe it boils down to one being idempotent (PUT) versus non-idempotent (POST). Idempotent is all about cause and effect; given a single cause, is the effect limited or widespread. In this context, how many times can you issue a command (PUT or POST) and have the outcome update/create one and only one resource (PUT) or produce multiple resources in correlation to the number of time you invoked the command (POST).

So if you only want ONE resource to be affected regardless of how many times you make a call, then PUT is the right command. If you want 10 or 20 resources to be affected (created), then you’d call the POST command 10 or 20 times, respectively.

Anant Sharma

post: create
put: update & replace 😉

ambator

If the ID is generated externally you should use PUT to create new entities. e.g. if you use employeeId generated in a different system and you want to create an employee object in your system, you can safely use PUT for both creates and updates.
It is idempotent, request can be repeated, the first one will create a record and the further requests will update (with the same value). Idempotent calls are safer.
However, if the ID is generated by the target system you cannot use PUT, you need to provide POST operation. e.g. if your accounting system records invoices generation unique invoice numbers, then an external system cannot create a new invoice with PUT accounting/invoice/{ID} as the id does not exist yet. A POST accounting/invoice/ can be used and the ID is generated by the system.

Diwas Poudel

We can use PUT method even the ID is generated by target system.Its just an standard to use POST for inserting new record and PUT for updating existing record.

If I am wrong correct me?

Last edited 3 years ago by Diwas Poudel
Brian

In my opinion, or rather in my interpretation, a PUT without a client provided ID cannot be idempotent because there is nothing in the URI that identifies the singular resource that is being “PUT”.

Technically you could allow the server to determine the identity of the resource by examining a known identifier within the body of the PUT request.

However, I believe the beauty of idempotence as it pertains to HTTP requests is in the URI being the single determining factor of identification because of the fact that it is by definition a uniform resource identifier.

Rohit Jain

What will happen if I am calling the POST request with same employee ID.
First time it will create the new resource and the next time i am calling with same identifier then what exception i will get or what will happen,

Learning

You will going to get unexpected error occurred, because it need some variation in its source.

Syed

You cannot call a POST request with a parameter. POST request-URI should be of a collection URI for eg /device-management/devices

Syed

And even in your request body, you cannot pass employee ID as you will not have one if it’s a genuine POST request, you can only pass an Employee object without an Id

Colm

Hi, I’ve a question regarding using PUT both for creation and updating.

For our addresses API, we can identify a unique address by it’s customer id (that owns it) and the address type it is (Communications/Billing/Delivery etc.).

Each customer are allowed to have any number of addresses so long as they are each a unique address type.

Essentially each address in the system can be identified by a combination of the customer id and an address type code.

As such, we settled with allowing clients to create or update a specific address by sending a PUT request to a URL of the structure …/addresses/{customerId}/{addressTypeCode}, e.g., …/addresses/1234/COM

If no address exists, it is created

If an address exists, it is updated

For consistency, we treat non-existent addresses as blank addresses, so if a GET is sent to …/addresses/1234/COM and no Communications Address exists for this customer, then a blank address is returned.

I’m curious whether this is in violation of the intended use of PUT and POST. My view is that if your resource is using a natural id, then there’s no need to POST to the collection to generate an id.

Sheik Hasan

Hi, does the PATCH return any body in postman? or just return only the Status?

Gaurav

Is graphql better than restful… or complete replacement of restful api’s. What do you think?

John

Late to the game here, but I prefer to create UUIDs for resources on the client and create them with a POST operation to the desired location /collection/{uuid} – how does this gel with you?

Cheers

John

Hadil Sabbagh

Which should I use for a translation REST API, e.g., from an XLSX spreadsheet to a CSV format?

Nigel
Angel Guevara

You should include that PUT doesnt support *enctype=’multipart/form-data’* which is needed to upload files.

Kym

The RFC that this post was based on has been superseded. Source https://tools.ietf.org/html/rfc2616

The particular section I want to highlight as a difference is this:

“The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. It essentially means that POST request-URI should be of a collection URI.
POST /questions”

The equivalent section in new RFC is at https://tools.ietf.org/html/rfc7231

The meaningful change is: “The POST method requests that the target resource process the representation enclosed in the request according to the resource’s own specific semantics.”

So essentially POST is less prescriptive on usage.

I think what this means is that the semantics of POST to create a sub-resource is still a good pattern to follow, it is an example usage even in the new RFC, however, we shouldn’t try to state that POST means create, that’s just one possibility.

The important points to follow with POST is that if a resource is created then a Location header must be specified and 201 response returned. We can also use hypermedia to describe to clients the behavior of POST.

GET /resource could return


{
  _links: {
    create: {href: "/resource", method: "post"}
  }
}

I would say OPTIONS /resource returning GET, POST, OPTIONS is not sufficient information to describe that POSTing will actually create a new resource.

Apologies for adding complexity to a really clearly laid out blog

Farheen Nilofer

This is the best post. I have searched this question on many websites but this answers in a single read. Thanks.

sirthomas

Very nicely done! The only stickler re idempotency on the PUT example is that many systems will implement some form of IAudit on editing operations, updating a “last edited timestamp” on the resource … in such case, the “update timestamp” for that resource would technically update automatically making the result of the operation not 100% identical (but prob 99.9%). But that does not change the essence of the topic.

JD

From https://tools.ietf.org/html/rfc7231#page-23:
Like the definition of safe, the idempotent property only applies to
what has been requested by the user; a server is free to log each
request separately, retain a revision control history, or implement
other non-idempotent side effects for each idempotent request.

I read this to say timestamps are server added and do not affect the idempotent property.

Amulya

Best post on PUT vs POST so far. Thanks a lot 🙂

joe

this was helpful, thank you!