Is body required in PUT request? - rest

I want to design my REST endpoint for enabling or disabling a user
My thought is to use PUT without body, with this URLs:
PUT /.../users/{userName}/enable
PUT /.../users/{userName}/disable
Is it possible to use PUT without a body?
Do you have any other suggestions?

Is body required in PUT request?
No - a PUT request with an empty body is how we would tell a web server that we want the representation of a resource to be zero bytes long.
PUT /example HTTP/1.0
Content-Type: text/plain
Content-Length: 0
I want to design my REST endpoint for enabling or disabling a user
A bit of prior art that you might consider is the github starring API, which uses PUT with an empty body to turn on a star, and DELETE to turn off a star.
Note that both requests use the same URI - that's appropriate because we want general purpose cache invalidation to "just work".
It may be helpful to be clear in your mind the differences between the semantics of the message ("please save this empty document on the web server") and the business side effects ("enable the user"). See Webber 2011.

Short answer: No.
Personally, I have also used empty PUT requests when merely updating a resource using an idempotent action - like toggling enable/disable.
Possible duplicate of: Is an HTTP PUT request required to include a body?

Related

Recommended or not: Sending a JSON body via POST HTTP Request without modification

Is it recommended to send a JSON body via a POST HTTP Request which doesn't modify anything?
Based on the link below, a Get request is not recommended to have a body. Thus, the other way is the one above.
HTTP GET with request body
Example:
Get the list of users, or anything for that matter based on parameters.
Http GET example.com/users
Body
{
name:"John",
age:1,
... long list of parameters
}
Is it recommended to send a JSON body via a POST HTTP Request which doesn't modify anything?
The rule is that POST is the default; it should be used unless there is something better.
For a request with "effectively read only" semantics, you want to use GET instead of POST... if it works. The challenge can be those cases where the request-target (aka: the URI) gets long enough that you start running into 414 URI Too Long responses. If your identifier is long enough that general purpose components refuse to pass the request along, then it is not something better, and you fall back to POST.
An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain. (HTTP Semantics, 9.3.1)
In other words, introducing a private agreement to include content in a GET request trades away inter-op, which - if you want "web scale" - is not a winning trade. So GET-with-a-body is not better, and you fall back to POST.
The HTTP working group has been working on semantics for a new "effectively-read-only-with-a-body" method token, which could prove to be an alternative for requests where you need to include a bunch of information in the body because it is too long to encode it into the URI. But we don't have a standard for that today, which means that it is not something better, and you fall back to POST.

Payload for PUT vs POST in REST API

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.

REST Api - Created resource redirect

I'm building REST API, and when resource is created normally I return HTTP 201 Created along with Location header to specify where that resource is located. But from some reason http client is not redirecting.
I'm using Postman for this. Does anyone have idea on this problem?
In short, a Location header is not sufficient to trigger a client redirect. It must be used in conjunction with a 3xx HTTP status code.
References:
https://en.m.wikipedia.org/wiki/HTTP_location
Redirecting with a 201 created
This is one of those things where the expectation does not meet what actually happens, and the first thing people think is "well that doesn't work properly", as has been suggested in other comments.
The Location is just a random header, and clients, such as Postman or curl or anything else need to be instructed to follow them. Most won't do this by default, as that is an unreasonable default.
YouTube for example returns a body for some responses and a Location tag too. One example would be video uploads. They respond to your original meta-data for the video is sent with a POST, and they shove a Location URL which is the endpoint to upload the video too. If clients just randomly redirected to that you'd be having a bad time.
You can use Paw to make a "sequence", which I believe will let you take values from headers to reuse. This is also possible with Runscope Ghostinspector.

Requesting RESTful GET with meaningful Body? Standards not clear

We found ourselves in a dead end when trying to follow standards as we need to build a request that should be a GET and should have a meaning Body.
The request just wants to retrieve some data, no modification inside the database, just getting some data. But at the same time we need to send an array of ids for the objects we want to retrieve, and no, these objects can't be indexed in any way so we really need to send the list of ids or alternatively make 100 requests to the server to get them one by one. That's not gonna happen.
We could also add the list to the URL, but we can't be sure the URL won't end up being too long if the list of ids were to be too big. So to ensure the system doesn't fail we want to use the Body.
I read that a GET can have a Body, but only if it isn't meaningful:
HTTP GET with request body
Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in
mind. Server semantics for GET, however, are restricted such that a
body, if any, has no semantic meaning to the request. The requirements
on parsing are separate from the requirements on method semantics.
So, yes, you can send a body with GET, and no, it is never useful to do so.
This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).
....Roy
But our Body IS meaningful, which takes us to have to decide between unfollowing HTTP standards or unfollowing REST standards.
Is there any alternative to that? (It's not that this blocks us but I would like to know the answer).
Thank you very much.
you should consider changing your request to POST method.
As I understand it, there are three potential issues with a GET with request body: (link to blog)
Not all servers will support this.
Not all tools will support this (Swagger, POSTMAN added support this year: https://github.com/postmanlabs/postman-app-support/issues/131)
There is not yet a consensus on GET with request body. (For example, is Dropbox still using a POST)
so you'll have problems process the body with GET

Can I change the headers of the HTTP request sent by the browser?

I'm looking into a restful design and would like to use the HTTP methods (POST, GET, ...) and HTTP headers as much as possible. I already found out that the HTTP methods PUT and DELETE are not supported from the browser.
Now I'm looking to get different representations of the same resource and would like to do this by changing the Accept header of the request. Depending on this Accept header, the server can serve a different view on the same resource.
Problem is that I didn't find a way to tell my browser to change this header.
The <a..> tag has a type attribute, that can have a mime type, looked like a good candidate but the header was still the browser default (in Firefox it can be changed in about:config with the network.http.accept.default key).
I would partially disagree with Milan's suggestion of embedding the requested representation in the URI.
If anyhow possible, URIs should only be used for addressing resources and not for tunneling HTTP methods/verbs. Eventually, specific business action (edit, lock, etc.) could be embedded in the URI if create (POST) or update (PUT) alone do not serve the purpose:
POST http://shonzilla.com/orders/08/165;edit
In the case of requesting a particular representation in URI you would need to disrupt your URI design eventually making it uglier, mixing two distinct REST concepts in the same place (i.e. URI) and making it harder to generically process requests on the server-side. What Milan is suggesting and many are doing the same, incl. Flickr, is exactly this.
Instead, a more RESTful approach would be using a separate place to encode preferred representation by using Accept HTTP header which is used for content negotiation where client tells to the server which content types it can handle/process and server tries to fulfill client's request. This approach is a part of HTTP 1.1 standard, software compliant and supported by web browsers as well.
Compare this:
GET /orders/08/165.xml HTTP/1.1
or
GET /orders/08/165&format=xml HTTP/1.1
to this:
GET /orders/08/165 HTTP/1.1
Accept: application/xml
From a web browser you can request any content type by using setRequestHeader method of XMLHttpRequest object. For example:
function getOrder(year, yearlyOrderId, contentType) {
var client = new XMLHttpRequest();
client.open("GET", "/order/" + year + "/" + yearlyOrderId);
client.setRequestHeader("Accept", contentType);
client.send(orderDetails);
}
To sum it up: the address, i.e. the URI of a resource should be independent of its representation and XMLHttpRequest.setRequestHeader method allows you to request any representation using the Accept HTTP header.
Cheers!
Shonzilla
I was looking to do exactly the same thing (RESTful web service), and I stumbled upon this firefox addon, which lets you modify the accept headers (actually, any request headers) for requests. It works perfectly.
https://addons.mozilla.org/en-US/firefox/addon/967/
I don't think it's possible to do it in the way you are trying to do it.
Indication of the accepted data format is usually done through adding the extension to the resource name. So, if you have resource like
/resources/resource
and GET /resources/resource returns its HTML representation, to indicate that you want its XML representation instead, you can use following pattern:
/resources/resource.xml
You have to do the accepted content type determination magic on the server side, then.
Or use Javascript as James suggests.
ModHeader extension for Google Chrome, is also a good option. You can just set the Headers you want and just enter the URL in the browser, it will automatically take the headers from the extension when you hit the url. Only thing is, it will send headers for each and every URL you will hit so you have to disable or delete it after use.
Use some javascript!
xmlhttp=new XMLHttpRequest();
xmlhttp.open('PUT',http://www.mydomain.org/documents/standards/browsers/supportlist)
xmlhttp.send("page content goes here");