Description
It seems like, broadly, there are two types of MAYs in the base spec.
The first describe elements that the server can optionally provide without the client explicitly requesting them, but that the client must know how to handle if they're present. Pagination links are a good example of this: if the client doesn't know how to follow them, it won't know how to get the whole collection. Meta information, "related"
urls, and which style of linkage to use are other examples too. Let's call these "server opt-in" features.
The second type are features that the client can optionally ask the server to provide, but that the server may or may not support. Here, I'm talking mainly about sorting and the inclusion of related resources. Let's call these "client opt-in" features. With these features, the client must have some way to detect whether it's request to use a feature was honored. For example, there's currently no way for a client that appends a sort
parameter to a request to know whether the server actually sorted the resources or just ignored the parameter. That's not good. With included resources, the story's a little better, because the client can check the response payload for the "included"
key, but might still be nice for clients to know in advance whether their include
parameter would be honored.
My proposal is that, because the client must be able to tell whether a "client opt-in" request was honored, all of these features should be defined as extensions, so that support for them can be detected with the supported-ext
parameter. And, now that we've allowed for multiple extensions to be used in tandem, this shouldn't cause any problems.
I think this distinction between "server opt-in" and "client opt-in" optional features, and only making extensions from the latter type, addresses @dgeb's comment in #432 that:
If every MAY in the base spec was eliminated, then a base implementation couldn't include self links, pagination links, related links, meta data, etc. and would require clients to negotiate for inclusion of any these. This seems unnecessarily strict and limiting by default.
Here's another advantage to this distinction: it captures the fact that "server opt-in" features are actually less optional than "client opt-in" ones. Yes, a server may or may not provide "related"
links but, if it does, a 1.0 client MUST know how to use these links to fetch the related resources. So, for clients, these optional features aren't optional. Meanwhile, the "client opt-in" features truly are optional for both parties: the client needn't request them and the server needn't support them. So it makes sense to treat these two classes of things differently, which is what making the latter into extensions does.
Going forward, all additions to JSON API are going to be either: 1) ignorable by older clients or 2) "client opt-in" features. None of them will be "server opt-in" features, in the sense that I've defined the term above, because requiring a client to know how to interpret payload fields that we add post 1.0 wouldn't be backwards compatible.
Thoughts on this?
Note: technically, creating/updating resources via POST and PATCH, which is optional for servers to support and clients to use, would fall into the category of "client opt-in" features. But there are already clear mechanisms in HTTP for the client to know in advance whether such requests would be supported (the Allow
header) and to see after the fact whether the request succeeded (the status code). So there's no need to broadcast that with supported-ext
.