REST API: Using content type vs custom param or endpoint - api

I'm designing a list endpoint for a resource that merits both full and light version of the resource called /transactions. By default, the response will include the complete resource, but there is also a need to provide clients with the "simplified" version of the resource list.
The first option is to use a custom param (e.g. /transactions?summary=true)
The second option is to use a custom endpoint, though not very RESTful (e.g. /transactions/summary)
The third option is to use content-type to allow a client to declare the alternative response body format. How would this look? (application/json+summary)? Are there any good examples of this being done?
Any other options come to mind?

The third option of using the Accept/Content-Type headers allows the media types to be a representation of a data, separate from the data itself.
A good example of this is github's API: https://developer.github.com/v3/media/
Which uses the http headers to allow clients to choose the format of the data, as well as the version. So in your case, the request could look something like:
curl http://api.host.com/transactions -H "Accept: application/summary+json"
And the response would contain a body of your simplified data format and the Content-Type header set to application/summary+json
If you want to be more pedantic about it, you could also use a vendor media type as application/vnd.yourcompany.summary+json. In this case, vnd implies that the media type is a vendor typically associated with application specific media types.
More Info:
Collection+JSON
A similar answer
A bit from restful API design

Related

RESTful Response when the POST request results in the creation of different kind of resources?

I have been working on designing an API that lets client create a product (think of product as something like website domain, something that comes into existence when client makes order for it to the service). Correspondingly with every purchase results in creation of the order object. Which means creation of two resources via a single POST request.
So afaik, the RFC standards recommends sending 201 on resource creation with URI for the resource in the Location header. But in the above scenario, we are creating two resources, domains and orders and I would want response to contain information related to both the resources.
Response would look something similar to this
POST /domains/
Request
body: {"domain_name": "awesome.com"},
Response
Body: {"order_id": "1234"}
Headers:
Location: http://example.com/awesome.com
But does not look very RESTful. I was wondering if there was a RESTful way to do this?
RFC 7231, section 6.3.2
The 201 (Created) status code indicates that the request has been fulfilled and has resulted in one or more new resources being created. The primary resource created by the request is identified by either a Location header field in the response or, if no Location field is received, by the effective request URI.
The 201 response payload typically describes and links to the resource(s) created.
In other words, on the web we would solve your riddle by returning an HTML document that includes hyperlinks to all of the created resources, along with text to describe each, so that the client would know which new identifiers are available.
To make such a response machine readable, we would do the work of documenting the schema of the message, so that specialized clients would know how to identify the semantics of each of the provided links.
The same idea works if you replace HTML with a different media type (for example application/json). You define the schema, and then specialized clients can parse the response to find the identifiers that they need.
Of course, REST is largely about standardizing things so that we can use general purpose components; application/json is somewhat inadequate here, as it doesn't include a URI type (just strings, which are too general). So to be more "RESTful", you would choose one of the specialized JSON types that has a general purpose representation of a link.
Sookocheff's article On Choosing a Hypermedia Type.... is a decent starting point for the kinds of questions you will want to be considering.

Could REST API OPTIONS be used as the HATEOAS only request?

As I've understood it, REST MUST use the HATEOAS constraint to be implemented properly. My understanding of HATEOAS is that basically every resource should share information about what communication options it has and how the consumer can use those options to achieve their end goal.
My question is if the HTTP OPTIONS method could be used as a way to navigate a REST API. Basically the response from an OPTIONS request would include the possible actions to take on a resource which would make it possible to consume the API without knowing the endpoints.
e.g.
An initial request to the API
HTTP OPTIONS /api
Could return all resources available for consumption and their relations. Like a massive tree to consume the API and all it has to offer. This idea doesn't neglect implementing HATEOAS on other responses as well, but the OPTIONS request would allow navigation without returning data that the consumer might not actually want to consume.
Is this a really bad idea? Or is it something that is commonly implemented. I'm currently attempting to implement a REST API but I'm having a hard time understanding the benefit of HATEOAS if there is no way to navigate the API without actually requesting data that you might not necessarily need when consuming certain end points. And I assume HATEOAS aims to make clients consume resources by their relation and not actually hard coding the end point?
TL;DR
Could HTTP OPTIONS request act as a way to navigate a REST API by returning what communication options are available for the requested resource without actually returning the resource?
According to RFC 7231
The OPTIONS HTTP method requests information about the communication options available for the target resource, at either the origin server or an intervening intermediary. This method allows a client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action.
...
A server generating a successful response to OPTIONS SHOULD send any header fields that might indicate optional features implemented by the server and applicable to the target resource (e.g., Allow), including potential extensions not defined by this specification. The response payload, if any, might also describe the communication options in a machine or human-readable representation. A standard format for such a representation is not defined by this specification, but might be defined by future extensions to HTTP. A server MUST generate a Content-Length field with a value of "0" if no payload body is to be sent in the response.
So, basically a response to an OPTIONS request will tell your client which HTTP operations may be performed on a certain resource. It is furthermore admissible to target the whole server on utilizing * instead of a specific resource URI.
A response to an OPTIONS request may look like this:
HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Date: Thu, 13 Oct 2016 11:45:00 GMT
Expires: Thu, 20 Oct 2016 11:45:00 GMT
Server: EOS (lax004/2813)
x-ec-custom-error: 1
which states that a certain resource supports the mentioned operations in the Allow header of the resonse. Via the Cache-Control header a client knows that it by default can cache responses of safe requests (GET and HEAD) for up to 7 days (value is mentioned in seconds). The x-ec-custom-error header specifies a non-standard header that is specific to a particular software, in that particular case to a ECS Server. According to this Q & A the meaning isn't publicly documented and therefore application specific.
In regards to returning a tree of traversable resources from the given resource the OPTIONS operation was requested for, technically this could be possible, however, certain systems might produce an almost never-ending list of URIs. Therefore such a design is questionable for larger systems.
My understanding of HATEOAS is that basically every resource should share information about what communication options it has and how the consumer can use those options to achieve their end goal.
Hypertext as the engine of application state (HATEOAS) is basically just a requirement to use the interaction model used on the Web for decades quite successfully and offer the same functionality to applications. This enabled applications to surf the Web similar like we humans do.
Great, but how does it work?
On the Web we use links and Web forms all the time. Through a Web form a server is able to teach a client basically what properties a certain resource supports or expects. But that's not all! The same form also tells your client where to send the request to (target URI), the HTTP method to use and, usually implicitly given, the media type the payload needs to be serialized to upon sending the request to the server. This, in essence, makes out-of-band API documentation unnecessary as all the information a client needs to make a valid request is given by the server already.
On a typical Web site you might have a table of entries which offers the option to add new entries, update or delete existing ones. Usually such links are hidden behind fancy images, i.e. a dustbin for deleting an entry and a pencil for editing an existing entry or the like where the image represents an affordance. The affordance of certain elements make it clear what you should do with it or what's the purpose of that element. A button on a page wants to be pushed while a slider widget wants to be changed while a text field waits for user input. As applications aren't that eager to work on images a further concept is used instead. Link relation names exactly serve this purpose. I.e. if you have a pageable collection consisting of multiple page à 25 entries i.e. you might be familiar with a widget containing arrows to page through that collection. A link here should usually be annotated with link relation names such as self, next, prev, first or last. The purpose of such links is quite clear, some others like prefetch, that indicates that a resource can be loaded in the background early as it is very likely that the next action may request it, might be less intuitive at first. Such link relation names should be standardized or at least follow the Web Linking extension mechanism.
Through the help of link-relation names a client that knows to look for URIs annotated with next i.e. will still work if the server decides to change its URI scheme as it treats the URI rather opaque.
Of course, both client and server need to support the same media type that furthermore is able to represent such capabilities. Plain application/json is i.e. not able to provide such a support. HAL JSON or JSON Hyper-Schema at least add support for links and link relation names to JSON based documents, while hal-forms, halo+json (halform) and ion might be used to teach a client how a request needs to be created. The question here shouldn't be which media type to support but how many different ones you want to support as the more media types your API is able to handle, the more likely it will be to interact with arbitrary clients not under your control.
These concepts allow you to basically use the controls given in the server response to "drive your workflow" forward. In essence, what you, as an API designer should do is to design the interactions of a client with your API so that it follows a certain, as Jim Webber termed it, domain application protocol or state machine as Asbjørn Ulsberg put it that basically guides a client through its task, i.e. ordering from your shop API.
So, in short, HATEOAS is comparable to Web surfing for applications by making use of named link relations and form-like media type representations that allow you to take actions solely on the response retrieved from a server directly instead of having to bake external knowledge stemming from some reference documentation page (Swagger, OpenAPI or the like) into your application.
But how does HATEOAS benefit the consumer in practice then?
First, it does not have to consult any external documentation other maybe than the current media type specification, though usually support for well-known media types is already backed into popular frameworks or at least allows to add support through plugins or further libraries. Once the media type is understood and supported interactions with all serivces that also support the same media type is possible, regardless of their domain. This allows to reuse the same client implementation to interact with service A and service B out of the box. In an RPC-like systems you'd need to integrate the API of service A first and if you want to interact with service B also you need to integrate those API separately. It's most likely that these APIs are incompatible and thus don't allow the reusage of the same classes.
Without knowing the URL for a resource, is the idea that the consumer can discover it by browsing the API, but they will still have a hard dependency on the actual URL? Or is HATEOAS purpose to leverage actions on a certain resource, i.e. the consumer knows the users end-point but he does not need to know the end-points for actions to take on the users resource cause those are provided by the API?
A client usually does not care about the URI itself, it cares about the content a URI may provide. Compare this to your typical browsing behavior. Do you prefer a meaningful text that summarizes that links content so you can decide whether to request that resource or do you prefer parsing and dissecting a URI to learn what it might do? Minifying or obfuscating URIs will do you no favor in the latter case though.
A further danger arise from URIs and resources that a client put meaning to. A slopy developer will interpret such URIs/resources and implement a tiny hack to interact with that service assuming the URI/resource will remain static. I.e. it is not unreasonable to consider a URI /api/users/1 to return some user related data and based on the response format a tiny Java class is written that expects to receive a field for username and one for email i.e.. If the server now decides to add additional data or rename its fields, the client suddenly will not be able to interact with that service further. And rest assured that in practice, especially in the EDI domain, you will have to interact with clients that are not meant to interact with the Web or where programmers implemented their own JSON framework that can't coope with changing orders of elements or can't handle additional optional fields, even though the spec contains notes on those issues. Fielding claimed that
A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names. [ditto] (Source)
Instead of typed resources content type negotiation should be used to support interoperability of different stackholders in the network.
As such, the URI itself is just the identifier of a resource that is mainly used to learn where to send a request to. Through the help of meaningful link relation names a client should know that it is interested in i.e. http:/www.acme.com/rel/orders if it wants to send an order to the service and just looks up the URI that either is annotated with that Web Linking extension realtion name or that has an URI attached to it. Whether the link relation name is just an annotation (i.e. a further attribute on the URI element) or the URI being attached to the link-relation name (i.e. as an embedded object of the link relation name) is dependent on the actual media type. This way, if a server ever decides to change its URI scheme or move around resources, for whatever reason, the client will still be able to find the URI that way and it couldn't care less about the characters present in the URI or not. It just treats the URI as opaque thing. The nice thing here is, that a URI can be annotated with multiple link relation names simultaneously, which allows a server to "offer" that URI to clients that support different link-relation names. In the case of forms the URI to send the request to is probably contained in the action attribute of the form element or the like.
As you hopefully can see, with HATEOAS there is no need for a hard dependency on URIs, if so there may be a dependency on the link-relation name though. It still requires URIs to learn where to send the request to, but through looking up the URI via its accompanying link relation name you make the handling of URIs much more dynamic as it allows a server to change the URI anytime it wants to or has to.

What is profile in accept heading of wiki api request

For example, when you perform an call from summary api of wikipedia, there is this header in the request
accept:application/json; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/Summary/1.3.7"
What is the purpose of this particular bit. I would like to understand since the value changes when you, for example, use the VisualEditor or access the api with different mean.
profile="https://www.mediawiki.org/wiki/Specs/Summary/1.3.7"
This specifies the response format and provides convenient access to a human-readable documentation.
The URL in your header leads to nowhere, but https://www.mediawiki.org/wiki/Specs/Summary/1.3.0 does exist and is probably valid for 1.3.7 as well.

How To Define API Blueprint X-Auth-Token Header

I have a number of services that require an X-Auth-Token header to be sent similar to the below:
X-Auth-Token: 2e5db4a3-c80f-4cfe-ad35-7e781928f7a2
I would like to be able to specify this in my API documentation following the API Blueprint standard. However, from what I can tell from the API Blueprint headers section definition, you can only specify literal values (e.g. Accept-Charset: utf-8) and not a schema for what the header should look like (e.g. something like X-Auth-Token (string)).
I get the impression that Traits might help with this problem but it's a little over my head at the moment. Can anyone tell me how to specify that all requests to a given action (or set of actions) require an X-Auth-Token header?
You are right about not being able to define a schema for headers. Unfortunately, API Blueprint doesn't support it yet.
Until something like that is supported, you can use the literal value for the header like the following:
+ Headers
X-Auth-Token: 2e5db4a3-c80f-4cfe-ad35-7e781928f7a2
API Blueprint also does not support any Traits currently. I am afraid you might have been confused by reading other feature requests.

Structuring online documentation for a REST API

I'm building my first Rest API which serialize data to JSON and XML formats.
I would like to provide an index page to API clients, where they would be able to choose implemented endpoints.
What information do I need to include to make my API most useful, and how should I organize it?
That's a very complex question for a simple answer.
You may want to take a look at existing API frameworks, like Swagger Specification (OpenAPI), and services like apiary.io and apiblueprint.org.
Also, here's an example of the same REST API described, organized and even styled in three different ways. It may be a good start for you to learn from existing common ways.
https://api.coinsecure.in/v1
https://api.coinsecure.in/v1/originalUI
https://api.coinsecure.in/v1/slateUI#!/Blockchain_Tools/v1_bitcoin_search_txid
At the very top level I think quality REST API docs require at least the following:
a list of all your API endpoints (base/relative URLs)
corresponding HTTP GET/POST/... method type for each endpoint
request/response MIME-type (how to encode params and parse replies)
a sample request/response, including HTTP headers
type and format specified for all params, including those in the URL, body and headers
a brief text description and important notes
a short code snippet showing the use of the endpoint in popular web programming languages
Also there are a lot of JSON/XML-based doc frameworks which can parse your API definition or schema and generate a convenient set of docs for you. But the choice for a doc generation system depends on your project, language, development environment and many other things.