Clarification on using Http PUT & POST and their differences - rest

I found this good post about understanding Http PUT & POST.
http://www.elharo.com/blog/software-development/web-development/2005/12/08/post-vs-put/
So the take away from the post are:
PUT:
PUT puts a page at a specific URL. If there is already a page there, it’s replaced. If there’s no page, a new one is created.
PUT is a limited operation that never does anything more than PUT one page at a specified URL.
PUT should be used when the client specifies the location for the page. e.g giving id of the object in a database table.
POST:
POST sends some data to a specified URL. The server on the other end of this URL can do whatever it wants with this data. It can store it in a new page, It can insert, update, or delete records in a database, It can start brewing coffee etc.
POST is used when the client sends the page to the server, and the server then tells the client where it put it. e.g after insertion in database returns generated id.
All good, but I have following questions:
I know it is possible to create new objects using PUT. That means even if I don't specify the location or id where object should be put, PUT method works. So, the statement made by the author PUT should be used when the client specifies the location for the page makes little sense or unconvincing when deciding when to use PUT.
My second question is regarding this statement POST sends some data to a specified URL. The server on the other end of this URL can do whatever it wants with this data. But the same is possible with PUT method once the data has been received on the server. Which leads to conflict with his another statement PUT is a limited operation that never does anything more than PUT one page at a specified URL.
Finally, are Http methods(PUT, POST, GET etc) more of a design concept or have technical implications when used.

POST is used to create new object while PUT is used to update existing object.
If a server doesn't respect this rule it breaks the semantic.

Your question #3 is on the right track: The HTTP methods don't have a technical implication on their own, but display a certain intent. These are defined in for example RFC 7231 / Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
Theoretically, nothing stops you from implementing software that listens on a DELETE to trigger something other than a delete, create new entities from a PUT or delete when receiving a POST. Is that useful? Probably not, but definitely not impossible.
The HTTP methods are well defined as a kind of contract how they should be used, to allow interaction between different software components.

The Page analogy you gave doesnt fit into the context of PUT and POST.
PUT,POST,GET,DELETE etc are all HTTP operations to do certain operations on a resource
Let us consider a simple resource , this enpoint is written by a pet house who wants to track dogs through a REST based back-end(server side software)
/dogs
When we want to add a dog to the records of dogs, we do a
POST /dogs with body
{
color:'black'
breed:'xyz'
puppies: 0
bla
bla
bla
}
It creates a new dog under /dogs resource with a unique identifier say identifier 1
Now the owner of the pet house wants to see all the dogs he/she has so the call made is
GET /dogs
This will list all the dogs and I can see what colour, what bred they are etc etc etc
I want to see a specific Dog, what do I call
GET /dogs/1 (Here 1 is the Identifier of the dog)
Which gives all details of Dog with identifier 1
Now let us say the Dog now gets married and has puppies (just so that it looks good socially) and we want to update the number of puppies to 3, what do you do
PUT /dogs/1 with body
{
color:'black'
breed:'xyz'
puppies: 3
bla
bla
bla
}
and now the record of Dog 1 is updated.
Now the unfortunate moment the Dog dies , the owner makes this call
DELETE /dogs/1 and that resource is deleted from the records.
Another thing to understand is PUT is idempotent POST is not which means if you do
POST /dogs for 10 times 10 different instances of dogs are created
if you do for 10 times
PUT /dogs/1 , it still does the same thing to that 1 dog.

HTTP methods are more about semantics than actual implementations (that answers your 3rd question I guess). I would suggest that don't take any single person's opinion literally.
In general, I believe the following is true
PUT
PUT needs an identifier in the url. And it will replace existing resource with whatever you provided. Replace here is important because, if you need partial updates, you should go for PATCH instead. If you expect the server to create a resource, you should call POST and not PUT. Calling a PUT with an imaginary id and expecting server to create the resource with that id does not make sense. Now this is what should be followed, but I have seen code which does otherwise just for convenience :)
POST
POST should always create a resource. If the resource with similar details already exists, service may choose to return some kind of error code to denote that (may be 400 or 409)

Related

REST API - PUT or GET?

I am designing and building a REST API. I understand the basic concept underlying the different request types. In particular PUT requests are intended for updating data.
I have a number of cases where an API call will modify the database, changing the values of a data object's attributes. However, the new values are not sent by the client but rather are implicit in the specific endpoint invoked. There are arguments needed to select the object to be modified, but not to supply attribute values for that object.
Originally I set these up to be PUT requests. However, I am now wondering whether they should be GET requests instead, because the body does not in fact contain update data.
Which would be recommended?
Just because the body doesn't contain update data doesn't mean it is not an update. Look at it from user's or at least from your API user's point of view. Is it an update from their point of view or retrieval of an object where update is not important from their point of view. If it is an update from user's point of view use PUT.
Originally I set these up to be PUT requests. However, I am now wondering whether they should be GET requests instead, because the body does not in fact contain update data.
If the semantics of the request are a change to the representation(s) of a resource on the server, then GET is inappropriate.
If the payload/entity enclosed in the request is not a candidate representation of the target resource ("make your representation look like this one right here"), then PUT is inappropriate.
"Update yourself however you see fit, here is some information that will help" will normally use POST.
POST serves many useful purposes in HTTP, including the general purpose of "this action isn’t worth standardizing." -- Roy Fielding, 2009
POST is the general solution for requests that are intended to modify resource state; PUT (and PATCH) are specializations with narrower semantics (specifically, remote authoring).

What happens if i try to post one POST request with existing record in the database

As per my knowledge the main difference between PUT and POST method in REST is that POST request will create a new record where as PUT request will update the existing record/ create new record if not present.
Now my question is that :
Suppose we have a User with Id = 1 and name= "Pritam" in database.
Now if i try to make a POST request with request body Id = 1 and name= "Pritam", then what happens. (Duplicate records). will a new record will get created or what happens exactly.
Please help me to understand the difference between PUT and POST method. When to use PUT and When to use POST in real time scenarios.
As per my knowledge the main difference between PUT and POST method in REST is that POST request will create a new record where as PUT request will update the existing record/ create new record if not present.
That's not right. (It's also not your fault -- that misunderstanding is common). The real differences in the semantics of POST and PUT are currently described by RFC 7231
POST is the more general method, which can be used for any operation on the target resource
PUT is more specific - it indicates that the included document is intended as a replacement for the representation on the server.
Suppose we have a User with Id = 1 and name= "Pritam" in database. Now if i try to make a POST request with request body Id = 1 and name= "Pritam", then what happens. (Duplicate records). will a new record will get created or what happens exactly.
Those are implementation details; precisely the sort of thing that the REST API is insulating the client from needing to understand (as far as the client is concerned, the server is just a web site).
The "right" thing in your domain might be:
create a new user in your domain model, using the information in the POST message-body, and possibly creating a duplicate, or
report an error to the client, because of the conflict
report success to the client, with reference to the previously created user
None of those things happens by magic, you actually have to choose what makes sense for your circumstances and implement it, then work out the right way to describe what has happened in the body of the HTTP Response, and what information to include in the metadata so that generic components can intelligently participate in the exchange.

Should I return id of associated entity or whole entity

OK, lets assume we have two entities: Profile, consisting of id, name and ~10 irrelevant fields, and Post, consisting of text, title, and it's author (Profile). Also, there is resource /feed that returns feed containing posts from different profiles.
So I have two options:
Send full Profile entity in author
Send author's id (there is a way to request Profiles separately)
Which way is faster (in terms on using it on front end) and more convenient (RESTy, if you like).
Obviously just sending the id of Profile is faster because the response length is smaller.
The important question, however, do you need the full Profile object with each Post? If you want to, for example, print out the name of the author for each Post then sending the full object makes more sense. But if you want to just supply a link to the author with each Post (in the front end) then the id should be enough.
For other services that query yours for Posts just send the id and have them make a second call if they need. They can always cache the data on their end if needed.
Try to build your service so that each call/endpoint returns the bare minimum amount of data needed to make sense of the response. This might mean that a Post contains a lean Profile object where only the name is included but all the other, "irrelevant", fields are excluded. But when you query a Profile directly, you get the full object.
You can also have an optional query parameter where the caller can specify whether they want just the id or the full Profile, this is a strategy Atlassian JIRA uses to preserve bandwidth and improve speed.
Also check out the hal+json specification, it can give you good ideas about how to design a more usable and transparent REST service.
MOST IMPORTANT! Your endpoints should only return data that the outside world can actually use and make sense of. So that means if Profile has a field/fields which values are only used in your back-end (like, for example, the user's password) then you should never leak those out.

Is HTTP method POST necessarily idempotent?

I'm stuck in a theoretical issue with REST.
Imagine a simple product stock API. The database contains one collection of movements referencing a product, a quantity and a status.
I have one prerequisite: I don't want the API users to manipulate the status. The status value can be reserved or confirmed.
First, I want to create a reservation of a product. Here is the corresponding URL path and HTTP method to represent that:
[POST] /products/{product-id}/reservations
This create the movement with a status reserved and return the id of the created movement.
Now, I want to confirm this reservation:
[POST] /reservations/{movement-id}/confirmations
In a semantic way, it seems to me that I create a confirmed reservation. In fact, I just change the status of the movement.
So, 2 questions:
My second POST is idempotent. I was unable to find the information in the RFC, but can a POST be idempotent?
Do you see a better way to represent the confirmation?
I would use PUT instead. e.g. PUT /reservations/{movement-id}/status "confirmed".
note:
It does not matter that your POST is idempotent, since you remove the link after the reservation was confirmed (HATEOAS), so the chance is very low that 2 confirmation arrive for the same reservation. Anyways I think PUT is a better fit.

What is the proper HTTP method for modifying a subordinate of the named resource?

I am creating a web client which has the purpose of modifying a set of database tables by adding records to them and removing records from them. It must do so atomically, so both deletion and insertion must be done with a single HTTP request. Clearly, this is a write operation of some sort, but I struggle to identify which method is appropriate.
POST seemed right at first, except that RFC 2616 specifies that a POST request must describe "a new subordinate" of the named resource. That isn't quite what I'm doing here.
PUT can be used to make changes to existing things, so that seemed about right, except that RFC 2616 also specifies that "the URI in a PUT request identifies the entity enclosed with the request [...] and the server MUST NOT attempt to apply the request to some other resource," which rules that method out because my URI does not directly specify the database tables.
PATCH seemed closer - now I am not cheating by only partly overwriting a resource - but RFC 5789 makes it clear that this method, like PUT, must actually modify the resource specified by the URI, not some subordinate resource.
So what method should I be using?
Or, more broadly for the benefit of other users:
For a request to X, you use
POST to create a new subordinate of X,
PUT to create a new X,
PATCH to modify X.
But what method should you use if you want to modify a subordinate of X?
To start.. not everything has to be REST. If REST is your hammer, everything may look like a nail.
If you really want to conform to REST ideals, PATCH is kind of out of the question. You're only really supposed to transfer state.
So the common 'solution' to this problem is to work outside the resources that you already have, but invent a new resource that represents the 'transaction' you wish to perform. This transaction can contain information about the operations you're doing in sequence, potentially atomically.
This allows you to PUT (or maybe POST) the transaction, and if needed, also GET the current state of the transaction to find out if it was successful.
In most designs this is not really appropriate though, and you should just fall back on POST and define a simple rpc-style action you perform on the parent.
First, allow me to correct your understanding of these methods.
POST is all about creating a brand new resource. You send some data to the server, and expect a response back saying where this new resource is created. The expectation would be that if you POST to /things/ the new resource will be stored at /things/theNewThing/. With POST you leave it to the server to decide the name of the resource that was created. Sending multiple identical POST requests results in multiple resources, each their own 'thing' with their own URI (unless the server has some additional logic to detect the duplicates).
PUT is mostly about creating a resource. The first major difference between PUT and POST is that PUT leaves the client in control of the URI. Generally, you don't really want this, but that's getting of the point. The other thing that PUT does, is not modify, if you read the specification carefully, it states that you replace what ever resource is at a URI with a brand new version. This has the appearance of making a modification, but is actually just a brand new resource at the same URI.
PATCH is for, as the name suggest, PATCHing a resource. You send a data to the server describing how to modify a particular resource. Consider a huge resource, PATCH allows you to send just the tiny bit of data that you wish to change, whilst PUT would require you send the entire new version.
Next, consider the resources. You have a set of tables each with many rows, that equates to a set of collections with many resources. Now, your problem is that you want to be able to atomically add resources and remove them at the same time. So you can't just POST then DELETE, as that's clearly not atomic. PATCHing the table how ever can be...
{ "add": [
{ /* a resource */ },
{ /* a resource */ } ],
"remove" : [ "id one", "id two" ] }
In that one body, we have sent the data to the server to both create two resources and delete two resources in the server. Now, there is a draw back to this, and that is that it's hard to let clients know what is going on. There's no 'proper' way of the client of the two new resources, 204 created is sort of there, but is meant have a header for the URI of the one new resource... but we added two. Sadly, this a problem you are going to face no matter what, HTTP simple isn't designed to handle multiple resources at once.
Transaction Resources
So this is a common solution people propose, and I think it stinks. The basic idea is that you first POST/PUT a blob of data on the server the encodes the transaction you wish to make. You then use another method to 'activate' this transaction.
Well hang on... that's two requests... it sends the same data that you would via PATCH and then you have fudge HTTP even more in order to somehow 'activate' this transaction. And what's more, we have this 'transaction' resource now floating around! What do we even do with that?
I know this question has been asked already some time ago, but I thought I should provide some commentary to this myself. This is actually not a real "answer" but a response to thecoshman's answer. Unfortunately, I am unable to comment on his answer which would be the right thing to do, but I don't have enough "reputation" which is a strange (and unnecessary) concept, IMHO.
So, now on to my comment for #thecoshman:
You seem to question the concept of "transactional resources" but in your answer it looks to me that you might have misunderstood the concept of them. In your answer, you describe that you first do a POST with the resource and the associated transaction and then POST another resource to "activate" this transaction. But I believe the concept of transactional resources are somehow different.
Let me give you a simple example:
In a system you have a "customer" resource and his address with customer as the primary (or named) resource and the address being the subordinate address. For this example, let us assume we have a customer with a customerId of 1234. The URI to reach this customer would be /api/customer/1234. So, how would you now just update the customer's address without having to update the entire customer resource? You could define a "transaction resource" called "updateCustomerAddress". With that you would then POST the updated customer address data (JSON or even XML) to the following URI: POST /api/customer/1234/updateCustomerAddress. The service would then create this new transactional resource to be applied to the customer with customerId=1234. Once the transaction resource has been created, the call would return with 201, although the actual change may not have been applied to the customer resource. So a subsequent GET /api/customer/1234 may return the old address, or already the new and updated address. This supports well an asynchronous model for updating subordinate resources, or even named resources.
And what would we do with the created transactional resource? It would be completely opaque to the client and discarded as soon as the transaction has been completed. So the call may actually not return a URI of the transactional resource since it may have disappeared already by the time a client would try to access it.
As you can see, transactional resources should not require two HTTP calls to a service and can be done in just one.
RFC 2616 is obsolete. Please read RFC 723* instead, in particular https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.3.