I've been learning how to build an ASP.NET Core Web API using the official documentation. However, under the PUT section it says:
According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. To support partial updates, use HTTP PATCH.
I know that POST is used to create a new resource and PUT is used to update a particular resource. But I cannot understand what is meant by "entire updated entity, not just the changes".
I cannot understand what is meant by "entire updated entity, not just the changes".
You should review the HTTP specification, which describes the semantics of PUT.
A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response.
Representation here refers to the bytes that would appear as the payload of the GET request. For a web page, we're talking about the HTML. For a resouce that responds with application/json, we're talking about the entire json document.
In other words, if you want to create/edit a json document, and save it on the web server, then you use HTTP PUT, and the payload of the request should be the entire JSON document.
For cases where the JSON document is very big (much bigger than the HTTP headers) and the changes you are making are small, then you might instead choose to send the changes in a patch request, where the payload of the request is a patch document (probably JSON Patch or JSON Merge Patch
Now, here's the magic trick -- everybody on the web understands HTTP requests the same way. PUT always means PUT, PATCH always means PATCH. So you can use PUT and PATCH to make changes to things on the web that aren't really documents, but might instead be something else (like an entity).
That's pretty much the point of an HTTP API - it's a facade that (when seen from the outside) makes our service look like just another web server.
The fact that your resource is really rows in a database instead of a document on a file system is an implementation detail that is hidden behind the Web API.
Supposed you have a json Data like below
{
"Id":123,
"FirstName":"John",
"MiddleName":"Random",
"LastName":"Doe"
}
Suppose, you want to change middle name here. you want to remove it. You can use both put and patch to do so.
PUT
Here you've to send the whole new entity (the changed state of the json model) in your request. Though you're only changing the Middle name part, the full json data is being sent in the request payload
PUT /user?id=123
{
"Id":123,
"FirstName":"John",
"MiddleName":"", //Only this is being changed.
"LastName":"Doe"
}
PATCH
In this case, you can only send the diff between the old model and the new model, and that will be it. So, here, in this case, only the changes are being sent, not the whole updated entity
PATCH /user?id=123
{
"MiddleName":"", //Only this is being changed.
}
Using PATCH can be handy when you want to edit only a few properties of a huge object.
Related
I was asked below question in the Interview -
If you are hitting the same request with PUT and with POST http method then what will be the difference in payload?
Considering I don't have much experience working in REST, I didn't even know what payload is. I tried googling but didn't find anything conviencing.
Can anyone help?
according to this page restfulapi.net the PUT request should refer to already existing item (for example in a database connected). In other words, it is meant to update existing item. So the payload don't have to contain all the attributes of the item, just those you want to update.
On the other hand POST is meant to insert new item. This means that the payload should contain (almost) everything.
Thing is, if you send more same PUT requests, the item should remain equivalent to the situation with just one PUT send.
If you send two same POST requests then two new same items (with different ids) will be created. This means that POST requests are not idempotent.
Edit: here might be help too.
I didn't even know what payload is.
The interviewer is probably referring to the message-body of the HTTP Request (see RFC 7230).
If you are hitting the same request with PUT and with POST http method then what will be the difference in payload?
This is probably an attempt to explore whether you understand the difference in semantics between the HTTP POST method and the HTTP PUT method.
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.
Think "save file".
The instructions for POST are a lot less specific
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.
If that seems vague... you're right! The message-body of a POST request can mean almost anything. POST is the "junk drawer" of HTTP methods - anything not worth standardizing goes there.
I'm implementing a voting system (like/dislike) according to RESTful API and wondering what should I do if the intention is unknown while a request.
My real case:
If a user voting the first time - create a vote, if the user already has a vote - delete his vote (a vote can be only like or dislike, not 0). So what HTTP method and HTTP status code are suitable for this?
PUT sounds like a good option for this. PUT is used to create or replace the resource at the target uri.
PUT /article/[id]/myvote
When the vote is created, you can return 201. When it is overwritten, you can return 204 or 200.
My real case: If a user voting the first time - create a vote, if the user already has a vote - delete his vote (a vote can be only like or dislike, not 0).
How would you do it with a web site?
You would have some HTML page with a form on it; the form would include some input controls to collect information from the user. When the user submits the form, the browser would -- using the standardized HTML form processing rules, use the data and metadata of the form to create an application/x-www-form-urlencoded document, which it would send to the server as described by the form.
Supposing for this particular case that the action of voting is not "essentially read only", we would choose a form method that is not safe, which is to say POST.
The status codes to be returned would be exactly the same status codes (with the same meanings) that every other POST on the web uses. In particular, if the origin server successfully handles the request, then one of the 2xx status codes would be returned, with an appropriate entity and meta data.
If you aren't sure which 2xx code to use, 200 is the safe bet.
Remember, the world wide web is the reference implementation in the REST architectural style. You won't be far off if you storyboard a website, then use that to guide your api design.
There are other alternatives, that require a bit more thinking. One would be to treat the voter's ballot as a document that is stored on the origin server. The voter might GET a copy of his ballot, make local changes to it, and then request that the origin server apply those changes to its local copy of the ballot.
In that design, we would normally use PUT to copy our local edits to the web server; and the server would -- as before -- return some 2xx status code if request was successful.
The client, of course, will need to understand the representation of the ballot well enough to make the appropriate edits to it. You'll also need some sort of link convention that allows the client to find the right instance of ballot to edit.
The actual representation on the server doesn't need to be a document, of course. The document delivered to the origin server might instead be copied into rows in a relational database (an arbitrary example).
In the specific case of associating a representation (document) with a resource that previously didn't have one (in other words, if GET /ballot would have returned a 404), then the HTTP standard requires that you respond with a 201 status code, rather than a 200 status code, and include the appropriate metadata to identify the newly created resource.
GET /ballots/68D7165A-D172-4E32-84F3-E494A01B5C8E
404 Not Found
Ballot: /ballots/68D7165A-D172-4E32-84F3-E494A01B5C8E
has not yet been submitted
PUT /ballots/68D7165A-D172-4E32-84F3-E494A01B5C8E
Content-Type: text/plain
LIKE
201 Created
Location: /ballots/68D7165A-D172-4E32-84F3-E494A01B5C8E
Thank you for voting!
GET /ballots/68D7165A-D172-4E32-84F3-E494A01B5C8E
200 OK
Content-Type: text/plain
LIKE
I'm writing a stateless API. You send it a document, it processes the document, and then returns the processed document. I'm struggling to understand how the RESTFUL rules apply. I'm not retrieving data, creating data or updating data on the server. There is no data on the server. What do I need to use in this case as the http method and why?
Good news - you are right that it is confusing.
Nothing on the server changes in response to the request. That suggests that the request is safe. So GET is the natural choice here... BUT -- GET doesn't support message payloads
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
HEAD, the other ubiquitous safe method, has the same problem (and is unsuitable when you want to return a document in any case).
The straight forward thing to do at this point is just use POST. It's important to realize that POST doesn't promise that a request is unsafe, only that it doesn't promise that it is safe -- generic components won't know that the request is safe, and won't be able to take advantage of that.
Another possibility is to look through the method registry, to see if somebody has already specified a method that has the semantics that you want. Candidates include SEARCH and REPORT, from the WebDAV specifications. My read of those specifications is that they don't actually have the right semantics for your case.
A Lot of ways to do what you want. But here is a small guideline.
I would create an endpoint that receives the document:
/receive_document
with a 'POST' method. Since you are 'sending' your document to the server
I would create an endpoint that serves up the processed document:
/processed_document
with a 'GET' method. Since you want to retrieve / see your document from the server?
The problem that you are trying to solve is mainly related to the document size, and processing time before returning the response.
Theorically, in order to use a restful approach, you have an endpoint, like yourhost.com/api/document-manager (it can be a php script, or whatever you are using as backend).
OK, so instead of naming the endpoint differently for each operation type, you just change the HTTP method, I'll try to make an example:
POST: used to upload the document, returns 200 OK when the upload is completed.
GET: returns the processed document, you can also return a different HTTP code, in case the document is not ready or even different if the document hasn't been uploaded. 204 no content or 412 precondition failed can be good candidates in case of unavailable document. I'm not sure about the 412, seems like it's returned when you pass a header in the request, that tells the server which resource to return. In your case, I think that the user processes one document at time. But to make a more solid api, maybe you can return an ID token to the user, into the POST response, then forward that token to the GET request, so the server will be able to know exactly which file the user is requesting.
PUT: this method should be used when updating a resource that has been already created with POST
DELETE: removes a resource, then return 204 or 404
OPTIONS: the response contains the allowed methods on this endpoint. You can use it to know for example which privileges has the currently logged user on a resource.
HEAD: is the same as a GET call, but it shouldn't return the response body. This is another good candidate for you to know when the document has been processed. You can upload with POST, then when the upload is done, start some kind of polling to the same endpoint with the HEAD method, finally when it will return "found", the polling will stop, and make the final GET call, which will start the download of the processed document.
HTTP methods are a neat way of managing HTTP communications, if used properly are the way to go, and easily understandable by other developers. And not to forget, you don't have to invent lots of different names for your endpoints, one is enough.
Hope that this helped you a little... But there are loads of guides on the net.
Bye!
Let's say we have a collection resource called shelf (of book resources) and we would like to POST a new book:
[POST] /shelves/{shelf-id}/books [request body -- a book]
I know that the response should be either empty with a reference to the newly created resource (201) or include the created resource (200).
Let's say the clients that are creating book resources, will need to show summary of the shelf the new book is added to. One solution should be making clients to first do a POST (let's call it Req#1 -- to create the new book), and then a GET (Req#2) on the shelf resource to get the summary.
What if we care a lot about efficiency and want to return the result of Req#2 implicitly when getting Req#1 on the server and save one request on the client side? Is it OK based on REST principles to return the parent collection resource information in the response when a resource is added to the collection?
Any alternative design?
It's 'OK' for REST design to return different resource states, but HTTP doesn't have a standard way to do this. If you uses the HAL format for you REST api, it does have a way to do embedding, so I suppose you could embed different resources to the response of a POST request.
Note that there's no standard I know of that suggests that the following statement is true: I know that the response should be either empty with a reference to the newly created resource (201) or include the created resource (200).
Anyway, what are you trying to solve? Is it really that expensive to do an extra HTTP request? Where do you base that concern on? What's expensive about it? Is it the latency of having to do an extra roundtrip?
If that's the case, you could consider using HTTP/2 push to push a new version of your parent resource. It's probably the most standards compliant way. If your server and client support this well, then this also means you can use this as a great standard mechanism to push things to clients because they might soon request it.
I know that the response should be either empty with a reference to the newly created resource (201) or include the created resource (200).
This isn't true. According to the spec:
The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code.
In summary, use a 201 status response with information about the new resource. Please don't mix information about other resources with it. That is not RESTful, and apart from pedantry, it probably will make a messy API for very little benefit.
We are trying to implement a REST API for an application we have now. We want to expose read/write capabilities for various resources using the REST API. How do we implement the "form" part of this? I get how to expose "read" of our data by creating RESTful URLs that essentially function as method calls and return the data:
GET /restapi/myobject?param=object-id-maybe
...and an XML document representing some data structure is returned. Fine.
But, normally, in a web application, an "edit" would involve two requests: one to load the current version of the resources and populate the form with that data, and one to post the modified data back.
But I don't get how you would do the same thing with HTTP methods that REST is sort of mapped to. It's a PUT, right? Can someone explain this?
(Additional consideration: The UI would be primarily done with AJAX)
--
Update: That definitely helps. But, I am still a bit confused about the server side? Obviously, I am not simply dealing with files here. On the server, the code that answers the requests should be filtering the request method to determine what to do with it? Is that the "switch" between reads and writes?
There are many different alternatives you can use. A good solution is provided at the microformats wiki and has also been referenced by the RESTful JSON crew. As close as you can get to a standard, really.
Operate on a Record
GET /people/1
return the first record
DELETE /people/1
destroy the first record
POST /people/1?_method=DELETE
alias for DELETE, to compensate for browser limitations
GET /people/1/edit
return a form to edit the first record
PUT /people/1
submit fields for updating the first record
POST /people/1?_method=PUT
alias for PUT, to compensate for browser limitations
I think you need to separate data services from web UI. When providing data services, a RESTful system is entirely appropriate, including the use of verbs that browsers can't support (like PUT and DELETE).
When describing a UI, I think most people confuse "RESTful" with "nice, predictable URLs". I wouldn't be all that worried about a purely RESTful URL syntax when you're describing web UI.
If you're submitting the data via plain HTML, you're restricted to doing a POST based form. The URI that the POST request is sent to should not be the URI for the resource being modified. You should either POST to a collection resource that ADDs a newly created resource each time (with the URI for the new resource in the Location header and a 202 status code) or POST to an updater resource that updates a resource with a supplied URI in the request's content (or custom header).
If you're using an XmlHttpRequest object, you can set the method to PUT and submit the data to the resource's URI. This can also work with empty forms if the server supplies a valid URI for the yet-nonexistent resource. The first PUT would create the resource (returning 202). Subsequent PUTs will either do nothing if it's the same data or modify the existing resource (in either case a 200 is returned unless an error occurs).
The load should just be a normal GET request, and the saving of new data should be a POST to the URL which currently has the data...
For example, load the current data from http://www.example.com/record/matt-s-example and then, change the data, and POST back to the same URL with the new data.
A PUT request could be used when creating a new record (i.e. PUT the data at a URL which doesn't currently exist), but in practice just POSTing is probably a better approach to get started with.