Format for 406 Not Acceptable payload? - http

In a 406 Not Acceptable response:
The server SHOULD generate a payload containing a list of available
representation characteristics and corresponding resource identifiers
from which the user or user agent can choose the one most appropriate.
A user agent MAY automatically select the most appropriate choice from
that list. However, this specification does not define any standard
for such automatic selection, as described in RFC7231 Section 6.4.1.
Is there a preferred format for that "list of available representation characteristics and corresponding resource identifiers"?
I can send a response like:
{ Acceptable: ["application/json", "application/pdf"] }
But then I am assuming a default Content-Type for the 406 payload (JSON in this case).
Or should I send a very simple, almost format-less, payload like:
application/json,application/pdf

Is there a preferred format for that "list of available representation characteristics and corresponding resource identifiers"?
There's no standard for such payload.
You could choose any format that can be easily parsed by the user agent. In practice, both JSON or text should be fine:
{ "acceptable" : [ "application/json", "application/pdf" ] }
application/json,application/pdf
See the following quote from the section 6.4.1 of the RFC 7231, which is referenced in the 406 status code definition:
[...] A specific format for automatic selection is not defined by
this specification because HTTP tries to remain orthogonal to the
definition of its payloads. In practice, the representation is
provided in some easily parsed format believed to be acceptable to
the user agent, as determined by shared design or content
negotiation, or in some commonly accepted hypertext format. [...]
MDN Web Docs from Mozilla suggests the following:
[...] In reality, this error is very rarely used: instead of responding using this error code, which would be cryptic for the end user and difficult to fix, servers ignore the relevant header and serve an actual page to the user. It is assumed that even if the user won't be completely happy, they will prefer this to an error code. [...]

Related

What is the meaning of "contain an entity which describes the status of the request and refers to the new resource" in the HTTP/1.1 spec?

Chapter 9.5 POST of the HTTP/1.1 spec includes the sentence:
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header
It is referenced frequently. The itention is clear, but I have issues with the meaning of some of the chosen words.
What does "contain an entity which describes the status of the request and refers to the new resource" exactly mean?
How shall the entity (entity-header fields and entity-body) describe the status of the request? Isn't the status of the request 201 (Created)? Whow shall this status be described? Does "describe the status of the request" mean the result, in other words the current entity status?
Thinking of a Web API with JSON representation does it mean that the entity should be included in a JSON representation after a successful POST that created an entity? Thinking of a created image, should the image data be returned in the response body?
What is meant with refers to the new resource? The uri is already in the location header. Shall it be repeated in the body or does it mean just to add an id?
Is there a good source with examples of different entities and its responses to a creation POST?
I think it varies based on the resource you're creating, suppose your posting to a /profile/ resource maybe a payload containing multiple profile fields to update - your return would indicate it was successful and include a reference to the fields you posted (it can even return the entire profile attributes with fields you've updated including all fields);
Another example in the image sense, suppose you are posting a Base64 encoded image to a service that stores the image, the response should show the status (ie: accepted, rejected, file too larage, MIME type accurate or not, etc.) - and within the returned payload if successful you'd want the response to not be vague but return the path and/or filename of the image uploaded;
The header returns the response code - the body returns information related to the invoked action's entity response (it can be a set of fields, a URL, a useful response that when parsed back it can be actionable or informative);
These are principles of good coding, but also keep note of security and not to expose anything in a return that could potentially be damaging for example; when creating a service you want to be clear and provide concise and useful returns so when the client consumes the API it knows what to do, what to expect, etc.

What is the correct response format of a 406 HTTP status error

I want to issue a 406 Not Acceptable error in my application and I want to alert the client about the available alternative formats.
From the HTTP protocol spec:
Unless it was a HEAD request, the response SHOULD include an entity
containing a list of available entity 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. Depending upon the format and the
capabilities of the user agent, selection of the most appropriate
choice MAY be performed automatically. However, this specification
does not define any standard for such automatic selection.
Do I add that entity in the response body?
What's the format of that list?
The main thing in the spec is:
The entity format is specified by the media type given in the Content-Type header field
This page is quite useful:
http://chimera.labs.oreilly.com/books/1234000001708/apc.html#_proactive_negotiation
As-is the article it references:
http://bit.ly/agent-conneg
The examples there describe negotiation, in situations where you would return a 300 Multiple Choices response, a situation similar to how you might provide alternatives in a 406 Not Acceptable response. It follows the same ideas where you provide an entity in the format of the returning content type - if you are returning text, write some text; if you are returning HTML, write some HTML.
HTTP/1.1 300 Multiple Choices
Host: www.example.org
Content-Type: application/xhtml
Content-Length:XXX
<p>
Select one:
</p>
French
US English
German
A standard format would indeed be useful for automatic renegotiation, but the spec stays away from defining that. I would agree with the writer that the best way to inform of alternatives to a 406 is to use the same "Link" headers in the example from the oreilly.com page, as they describe:
An alternative approach is to use Link headers. This has the advantage of being a standard header that any client can understand. Here is an example:
HTTP/1.1 300 Multiple Choices
Host: www.example.org
Content-Length: 0
Link: <http://www.example.org/results/png>; type="image/png",
<http://www.example.org/results/jpeg>;type="image/jpeg",
<http://www.example.org/results/gif>;type="image/gif"
However, don't expect guaranteed results on every client with something that is not standardized.

Correct way to implement Http API method for exporting data to file

I'm implementing an API method that allows for exporting some data to a file. The format of the file is selected by the caller of the method.
The API method currently has an URI-form like so: /customers/{customerId}/shoppingchart/export/{fileTypeId} but what is the "correct" Http-way, if any, to implement the file type selection? Should the choice be specified by the Http Accept header or in the URI or some other way? And, what is the correct status to return if the asked format isn't supported?
I agree with the HTTP Accept header to specify the file type.
RFC 2616 states:
The Accept request-header field can be used to specify certain media types which are acceptable for the response.
However this does not indicate whether you can create your own custom types (should you wish that).
The HTTProtocol describes an Accept header as this:
This field contains a semicolon-separated list of representation schemes (Content-Type metainformation values) which will be accepted in the response to this request.
The above link then points to the definition of a Content-Type exactly. What's important here is
The x- convention for experimental types is of course still available as well.
This tells us that we can define our own custom types in an Accept header given that we prepend them with x- (e.g. x-ext for .ext files) as is common in the HTTProtocol.
What is the correct status to return if the asked format isn't supported?
I would argue HTTP 415 - Unsupported Media Type as defined in section 10.4.16 is appropriate here.
The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.

Different RESTful representations of the same resource

My application has a resource at /foo. Normally, it is represented by an HTTP response payload like this:
{"a": "some text", "b": "some text", "c": "some text", "d": "some text"}
The client doesn't always need all four members of this object. What is the RESTfully semantic way for the client to tell the server what it needs in the representation? e.g. if it wants:
{"a": "some text", "b": "some text", "d": "some text"}
How should it GET it? Some possibilities (I'm looking for correction if I misunderstand REST):
GET /foo?sections=a,b,d.
The query string (called a query string after all) seems to mean "find resources matching this condition and tell me about them", not "represent this resource to me according to this customization".
GET /foo/a+b+d My favorite if REST semantics doesn't cover this issue, because of its simplicity.
Breaks URI opacity, violating HATEOAS.
Seems to break the distinction between resource (the sole meaning of a URI is to identify one resource) and representation. But that's debatable because it's consistent with /widgets representing a presentable list of /widget/<id> resources, which I've never had a problem with.
Loosen my constraints, respond to GET /foo/a, etc, and have the client make a request per component of /foo it wants.
Multiplies overhead, which can become a nightmare if /foo has hundreds of components and the client needs 100 of those.
If I want to support an HTML representation of /foo, I have to use Ajax, which is problematic if I just want a single HTML page that can be crawled, rendered by minimalist browsers, etc.
To maintain HATEOAS, it also requires links to those "sub-resources" to exist within other representations, probably in /foo: {"a": {"url": "/foo/a", "content": "some text"}, ...}
GET /foo, Content-Type: application/json and {"sections": ["a","b","d"]} in the request body.
Unbookmarkable and uncacheable.
HTTP does not define body semantics for GET. It's legal HTTP but how can I guarantee some user's proxy doesn't strip the body from a GET request?
My REST client won't let me put a body on a GET request so I can't use that for testing.
A custom HTTP header: Sections-Needed: a,b,d
I'd rather avoid custom headers if possible.
Unbookmarkable and uncacheable.
POST /foo/requests, Content-Type: application/json and {"sections": ["a","b","d"]} in the request body. Receive a 201 with Location: /foo/requests/1. Then GET /foo/requests/1 to receive the desired representation of /foo
Clunky; requires back-and-forth and some weird-looking code.
Unbookmarkable and uncacheable since /foo/requests/1 is just an alias that would only be used once and only kept until it is requested.
I would suggest the querystring solution (your first). Your arguments against the other alternatives are good arguments (and ones that I've run into in practise when trying to solve the same problem). In particular, the "loosen the constraints/respond to foo/a" solution can work in limited cases, but introduces a lot of complexity into an API from both implementation and consumption and hasn't, in my experience, been worth the effort.
I'll weakly counter your "seems to mean" argument with a common example: consider the resource that is a large list of objects (GET /Customers). It's perfectly reasonable to page these objects, and it's commonplace to use the querystring to do that: GET /Customers?offset=100&take=50 as an example. In this case, the querystring isn't filtering on any property of the listed object, it's providing parameters for a sub-view of the object.
More concretely, I'd say that you can maintain consistency and HATEOAS through these criteria for use of the querystring:
the object returned should be the same entity as that returned from the Url without the querystring.
the Uri without the querystring should return the complete object - a superset of any view available with a querystring at the same Uri. So, if you cache the result of the undecorated Uri, you know you have the full entity.
the result returned for a given querystring should be deterministic, so that Uris with querystrings are easily cacheable
However, what to return for these Uris can sometimes pose more complex questions:
returning a different entity type for Uris differing only by querystring could be undesirable (/foo is an entity but foo/a is a string); the alternative is to return a partially-populated entity
if you do use different entity types for sub-queries then, if your /foo doesn't have an a, a 404 status is misleading (/foo does exist!), but an empty response may be equally confusing
returning a partially-populated entity may be undesirable, but returning part of an entity may not be possible, or may be more confusing
returning a partially populated entity may not be possible if you have a strong schema (if a is mandatory but the client requests only b, you are forced to return either a junk value for a, or an invalid object)
In the past, I have tried to resolve this by defining specific named "views" of required entities, and allowing a querystring like ?view=summary or ?view=totalsOnly - limiting the number of permutations. This also allows for definition of a subset of the entity that "makes sense" to the consumer of the service, and can be documented.
Ultimately, I think that this comes down to an issue of consistency more than anything: you can meet HATEOAS guidance using the querystring relatively easily, but the choices you make need to be consistent across your API and, I'd say, well documented.
I've decided on the following:
Supporting few member combinations: I'll come up with a name for each combination. e.g. if an article has members for author, date, and body, /article/some-slug will return all of it and /article/some-slug/meta will just return the author and date.
Supporting many combinations: I'll separate member names by hyphens: /foo/a-b-c.
Either way, I'll return a 404 if the combination is unsupported.
Architectural constraint
REST
Identifying resources
From the definition of REST:
a resource R is a temporally varying membership function MR(t), which for time t maps to a set of entities, or values, which are equivalent. The values in the set may be resource representations and/or resource identifiers.
A representation being an HTTP body and an identifier being a URL.
This is crucial. An identifier is just a value associated with other identifiers and representations. That's distinct from the identifier→representation mapping. The server can map whatever identifier it wants to any representation, as long as both are associated by the same resource.
It's up to the developer to come up with resource definitions that reasonably describe the business by thinking of categories of things like "users" and "posts".
HATEOAS
If I really care about perfect HATEOAS, I could put a hyperlink somewhere in the /foo representation to /foo/members, and that representation would just contain a hyperlink to every supported combination of members.
HTTP
From the definition of a URL:
The query component contains non-hierarchical data that, along with data in the path component, serves to identify a resource within the scope of the URI's scheme and naming authority (if any).
So /foo?sections=a,b,d and /foo?sections=b are distinct identifiers. But they can be associated within the same resource while being mapped to different representations.
HTTP's 404 code means that the server couldn't find anything to map the URL to, not that the URL is not associated with any resource.
Functionality
No browser or cache will ever have trouble with slashes or hyphens.
Actually it depends on the functionality of the resource.
If for example the resource represents an entity:
/customers/5
Here the '5' represents an id of the customer
Response:
{
"id": 5,
"name": "John",
"surename": "Doe",
"marital_status": "single",
"sex": "male",
...
}
So if we will examine it closely, each json property actually represents a field of the record on customer resource instance.
Let's assume consumer would like to get partial response, meaning, part of the fields. We can look at it as the consumer wants to have the ability to select the various fields via the request, which are interesting to him, but not more (in order to save traffic or performance, if part of the fields are hard to compute).
I think in this situation, the most readable and correct API would be (for example, get only name and surename)
/customers/5?fields=name,surename
Response:
{
"name": "John",
"surename": "Doe"
}
HTTP/1.1
if illegal field name is requested - 404 (Not Found) is returned
if different field names are requested - different responses will be generated, which also aligns with the caching.
Cons: if the same fields are requested, but the order is different between the fields (say: fields=id,name or fields=name,id), although the response is the same, those responses will be cached separately.
HATEOAS
In my opinion pure HATEOAS is not suitable for solving this particular problem. Because in order to achieve that, you need a separate resource for every permutation of field combinations, which is overkill, as it is bloating the API extensively (say you have 8 fields in a resource, you will need permutations!).
if you model resources only for the fields but not all the permutations, it has performance implications, e.g. you want to bring the number of round trips to minimum.
If a,b,c are property of a resource like admin for role property the right way is to use is the first way that you've suggested GET /foo?sections=a,b,d because in this case you would apply a filter to the foo collection. Otherwise if a,b and c are a singole resource of foo collection the the way that would follow is to do a series of GET requests /foo/a /foo/b /foo/c. This approach, as you said, has a high payload for request but it is the correct way to follow the approach Restfull. I would not use the second proposal made ​​by you because plus char in a url has a special meaning.
Another proposal is to abandon use GET and POST and create an action for the foo collection like so: /foo/filter or /foo/selection or any verb that represent an action on the collection. In this way, having a post request body, you can pass a json list of the resource you would.
you could use a second vendor media-type in the request header application/vnd.com.mycompany.resource.rep2, you can't bookmark this however, query-parameters are not cacheable (/foo?sections=a,b,c) you could take a look at matrix-parameters however regarding this question they should be cacheable URL matrix parameters vs. request parameters

Are PUT and POST requests required/expected to have a request body?

I'm writting a RESTful api, and at I'm thinking about the process of a user creating a key. I have the following possibilities:
GET request to /new/<keyname> - although it's very easy I think I won't use this, because I heard GET is for retrieving and/or listing information;
POST request to /<keyname> - This seemed to me easy and simple enough, but does not pass any data in the request body. Can I do it this way ? Is this weird ?
POST request to /keys passing in the request body "keyname=SomeKey" - Is this the correct way ?
I looked at this API from joyent and in all their PUT and POST requests they pass some data in the request body. Is this expected ? Is it really wrong not to require a request body in a PUT and POST request ?
I asked this question on the Http-WG. This was the most precise answer I got http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0276.html
In summary, POST does not require a body. I would expect the same justification can be applied to PUT.
RFC2616 is the base RFC for HTTP 1.1
In the most general form, an HTTP message is this (note the optional body):
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
Reading further gives this:
9.5 POST
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. ...
and
9.6 PUT
The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. ...
The fundamental difference between the POST and PUT requests is
reflected in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed
entity. That resource might be a data-accepting process, a gateway to
some other protocol, or a separate entity that accepts annotations.
In contrast, the URI in a PUT request identifies the entity enclosed
with the request -- the user agent knows what URI is intended and the
server MUST NOT attempt to apply the request to some other resource.
Both POST and PUT include the phrase entity enclosed in the request.
Based on my reading, I believe that a body is desired (a non-normative description, I know) for both POST and PUT.
In the context of REST, POST is create and PUT is update. I can imagine creating an empty object (perhaps a placeholder for future information), but I don't imagine much use of an empty update.
It is not required. You can send a POST/PUT request without a body and instead use query string parameters. But be careful if your parameters contain characters that are not HTTP valid you will have to encode them.
For example if you need to POST 'hello world' to and end point you would have to make it look like this: http://api.com?param=hello%20world
Probably the best way is your third option: POST to /keys with keyname=SomeKey.
Here's why: You may wish to add another function to your API, for example create_new_user. It would then be difficult to tell the difference between a user trying to POST a key called create_new_user and a user trying to use the create_new_user function.
You are correct in saying that you should not be using GET to do this operation as the GET operation "SHOULD NOT have the significance of taking an action
other than retrieval." (RFC 2616).
To answer your question in one line. Yes it is expected to have Body/Content in body, but it is not required(Mandatory).
According to okHttp3 (an HTTP library for android): the following methods need a body: POST, PUT, PATCH, PROPPATCH (WebDAV) and REPORT (source). It even crashes if you try to do a request with the given methods without a body.

Resources