REST-way to control whether to return representation of created resource in POST response - rest

Is there a "REST-way" by which a client of a REST-API can indicate whether it is interested in getting a resource representation of the created resource in the POST response or whether it is just interested in HTTP response code (i.e. 201 on success) and location header?
I was thinking on using the Accept header. If the client adds a media type to this header that is supported by the API, the representation will be returned. Otherwise, it will just get a HTTP Created and the location header.
Context: The API will have to types of clients. A Web-UI client, that wants the representation in the response to save a network round-trip. And backend-service clients that will create resources at high rate in fire-and-forget manner. They're only interested in response code and resource URI.

There is a HTTP header:
Prefer: return=representation
The server can signal that it respected the header by returning:
Preference-Applied: return=representation
https://www.rfc-editor.org/rfc/rfc7240

Related

What URI should be returned in HTTP Location header in REST response, if I have two URIs for the same resource?

Let's say I am modeling blogging REST API which has resources Blog, Post and Comment.
Then I add following URIs for Blog and Post resources:
/api/blogs
/api/blogs/{blogId}
/api/blogs/{blogId}/posts
and since deep nesting should be avoided I create separate endpoint for all Posts in order to get their Comment`s:
/api/posts
/api/posts/{postId}
/api/posts/{postId}/comments
Now, if I implement POST action that creates a new Post for a specific Blog on /api/blogs/{blogId}/posts endpoint, should I set Location header value in response to:
/api/blogs/{blogId}/posts/123
or
/api/posts/123
?
In either case I can GET the same resource, but is there some preference, according to REST style, which should be returned to client after successful POST?
If one or more resources has been created on the origin server as a result of successfully processing a POST request, the origin server SHOULD send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created (Section 7.1.2) and a representation that describes the status of the request while referring to the new resource(s). -- RFC 7231
Which resource is the "primary resource"? That's up to you - priority of the resources is going to depend on your resource model, and REST / HTTP do not care what model you use.
In effect, it comes down to "which URI do you want to see in your access logs?"

How do APIs receive the request's method, body, and headers?

The query URL / endpoint below seems to successfully make a request to the API resource and returns a JSON response:
https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia/all-access/all-agents/Albert_Einstein/daily/2015100100/2015103100
Given that a request is made up of not only the URL, but also of a method, headers, and body, could someone explain how the API knows which method to use, as well as how the headers and body get transmitted (if they did exist)?
Given that a request is made up of not only the URL, but also of a method, headers, and body, could someone explain how the API knows which method to use, as well as how the headers and body get transmitted (if they did exist)?
If I'm understanding your question correctly... the API doesn't know these things, the client knows these things.
Which is to say when I'm looking at your question in my web browser, what I'm really looking at is the web browsers interpretation of an HTML document. Because the web browser speaks HTML, it knows what <a href="..."> means; that the quoted text is an identifier for another resource that I the use might want to navigate to.
The browser also knows RFC 3986, so it knows how to parse the quoted string and extract from it the protocol, the host, and the target uri.
Because the browser also knows about https, it knows which port number it should default to when the port isn't specified.
Because the browser knows HTTP, it knows how to construct a valid HTTP request, and the semantics of the required and optional headers it might want to attach.
Because HTTP follows the REST architectural style, we also know that the interface is uniform -- all HTTP resources use the same semantics. So the browser doesn't need to know what the identifier is in order to know that GET, HEAD, OPTIONS are all safe. Similarly, the rules for authentication, caching, content-negotiation, and so on are all the same, so the browser can craft the appropriate headers as it generates the request.
For instance, the browser knows that it is itself HTML capable, so it includes headers that communicate a preference for an HTML or XHTML+xml representation of the resource, if one is available.
Were I to instead switch to the command line, I could use curl(1) to generate the http request instead, which would produce an HTTP request with different headers.
The browser (and curl) know not to send a body with a HEAD or GET request because the HTTP specification explains that the payload of a GET or HEAD request has no defined semantics.
On the API side of the conversation, the server knows about HTTP, so knows how to correctly interpret the bytes of the HTTP request. Thus, the server knows where to look in the request for the HTTP method, the target URI, the headers that may (or may not) modify the context of the request, and so on. The implementation can then do whatever it likes with that information, and construct a suitable HTTP response (in effect, lifting into the headers of the response the metadata in a representation that can be understood by all of the general purpose components participating in the conversation.

Is there a standard way for a REST API to request that 201 Created includes a body?

When designing an HTTP REST API, is there a standard way to request full entity bodies in 201 Created responses? I remember reading about it some time ago.
Found it: API can support Prefer request header to achieve this.
Prefer: return=representation requests a full response (e.g. entity body).
Prefer: return=minimal requests a minimal response (e.g. headers only).
This header is defined in RFC 7240 (Prefer Header for HTTP).

HTTP 303 See Other - Content

If I want to return a status code of 303 See Other when a client POSTs data that already exists, am I allowed to return that data in the content (body) of the response (in addition to setting Location), or must the client then GET the Location?
I would like to avoid requiring the client HTTP to make two HTTP calls if at all possible.
Idiomatically, the client should retrieve the data with a GET request.

Including created resource in HTTP POST response?

RFC7231 says a server should respond to a resource-creating POST request with status 201 and a Location header to the new resource. In some situations it could be convenient for the server to include a representation of the created resource in its response, but in other cases this would be a waste of bandwidth.
Might this be a good place for content negotiation within the post request? If so, what request headers should be sent to indicate that the client would like the resource returned in addition to the Location header?
I would suggest using the "Prefer" header:
Request:
PUT /xxx
Prefer: return=representation
Response:
201 Created
{ ... created resource representation ... }
See https://www.rfc-editor.org/rfc/rfc7240