The Definition Endpoint
One of the goals of the NARWHL framework is to develop APIs that are as automated as possible. Discoverability and dynamic client generation are both key to making this possible.
To do this, however, every resource should be responsible for defining what can request and should expect in the response. There are several formats that exist and are emerging to describe resource profiles, such as I/O Docs and RAML, but those details are covered elsewhere on this site.
Systems supporting these definitions should also support a consistent way for the client to find them. The “definitions” endpoint is one way the NAWHL framework supports these. For example, calling
/products/74921/definition
Should respond not with the representation of the requested resource, but with the definition of the resource itself. Similarly, requests to all resources should include a Link in the response header back to the definition for the resource. For example, a call to the resource URI
/products/74921
Should respond with the expected representation of the resource, but the response header should include
Link: <http://api.example.com/v1/products/definition>; rel=”service”
The “service” relationship is borrowed from the ATOM publishing protocol, where it serves a similar purpose.
The definition for a resource may also be obtained by using the HTTP method OPTIONS, so that a call to
OPTIONS /v1/products
would return the same definition document as a call to
GET /v1/products/definition
The reserved “definition” endpoint exists to serve those clients and server that are not able to use the OPTIONS method.
The Views Endpoint
The goal of any successful API is to make it easier for client developers to create applications with it. With that in mind, there will be situations where custom “helper” endpoints may be required to present views of data that are more helpful for developers to access. For example, if a developer is logged in on behalf of a Store Admin and they want to pull a report displaying the most popular items currently being sold, the system may compile this automatically on the back end and serve it from the URI
/products/views/best_sellers
The “views” endpoint separates these custom endpoints from the rest of the URI structure and indicates that the representation being returned is not a resource, but a specific view of that resource. These views may contain information compiled from other resources as well to create a more efficient response.
Caution must be taken when creating custom endpoints. Before creating them you should first try to access the data you need through standard calls and, if necessary, using the Zoom/Embed pattern. Creating too many one-off custom views can lead to an unmanageable and unwieldy API.
There is one fly in the ointment here re HTTP OPTIONS “Responses to this method are not cacheable.”
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2
Yup – and that’s one of the reasons I’ve hesitated to recommend this as the sole way to do things. It’s also used in some instances for CORS, which means it could get overloaded on APIs that serve HTML as one of their accepted responses.
Hallo,
I believe there a inconsistency in your explanation.
You describing the versioning in the URL /v1/resource but in the chapter content negotiation you place the version inside the media type. Whats the difference and why are you placing the version number inside the URL.
My understanding of RESTful design forbid this kind of meta information inside the URL. What are your thoughts about this topic?
Thanks for the hard work.
Best regards Vitaliy Schreibmann
In a truly, tightly religious RESTful world, you’re correct – the version should be completely out of the URI. And, as time has progressed, I’ve started getting more hardline on this. I need to flesh out the Content Negotiation and versioning stuff to better articulate this, but you’re correct – I believe the versioning should exist in the content type in the header. I left the v1 in the URI primarily as a safe guard until I felt completely confident that URI versioning was unnecessary. I’ll likely very soon remove that altogether and advocate solely for versioning in the content type.
Sorry it took so long to respond to this, but I genuinely appreciate you bringing this up.
Why would you use reserved endpoint to retrieve metadata? It is just different representation of the same resource and content negotiation seems more appropriate
Something along the lines of
Accepts: application/json+meta or custom type all together