[RFC] Standardising an OPTIONS response on a server that supports jsonapi

This quote is the crux, of why I want to get some discussion around this thread’s topic.

The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.

If the Request-URI is not an asterisk, the OPTIONS request applies only to the options that are available when communicating with that resource.

The response body, if any, SHOULD also include information about the communication options

The problem we are trying to solve, is getting our available “communication options”, from the server. This is exactly what the OPTIONS method tries to solve.

OPTIONS requests may include a body, and we can use this body to get exactly the type of “options” we care about a particular point in time. The OPTIONS body would include, all allowed methods, the attributes and relationships for the resource, and all query parameters.

In my opinion such a response should include validation information, for each of the attributes, such that the client can reasonably validate the content it is sending to the server, without making a round trip. This would be validations for length and for example format.

As an aside, my motivation for HATEOAS as a driving princaple in API design, is as follows.

Consider a regular website, that supports user registration. As a first pass the site requires, username and password, when you submit the form, you are registered. Later in the application’s life, we change the form to be: email and password. And later on we add extra fields, and we can do whatever!

None of this requires you to update your browser (the client), because the the server’s response is self contained. The client can always infer what actions it should take, by following links, or submitting forms.

You’re thinking of filtering on related resources then I presume? There might be a good case for that, but I suspect you would be better served by doing either of the following:

  1. Use a different representation model

  2. Use a different technical solution (e.g. GraphQL)

Not that many - you would need to remove or rename a previously allowed filter to break clients, adding a new filter wouldn’t be a breaking change.

Where a query parameter or attribute element is only allowed to have a restricted set of values (e.g. an enum, where a client might typically use a drop-down selector) I do like to have the API provide (via related resources) the list of allowed values rather than just put this in the API documentation (this way even removing an allowed value doesn’t break the client :slight_smile:). But currently I don’t believe this approach applies generally to filters though, due to the potential explosion of combinations when an API allows multiple filters.

I don’t think you need OPTIONS to do this though. Couldn’t you just use related resources (as per the IANA create-form and edit-form approach?

You’re still going to have to validate that data on the server anyway though. I can see that doing client-side validation might be attractive if the network is slow / not reliable, but I suspect you would have just as many problems downloading the validation information before submission as you would retrying after the server rejects the submission.

@jlangley Agreed, I originally looked at the create and edit form links. And this is another solution. But this requires adding a new top-level key in jsonapi, that would represent something analogous to a form, which I am not opposed to, and similar work will be needed for responses to an OPTIONS request, but…

My idea behind using OPTIONS, is that they can be conceptually separated from other requests/responses. If you make anything other than an OPTIONS request, you can safely assume your getting a resource back, and not a specification for a resource.

This would also be a non breaking change to the spec, ie. a jsonapi 1.0 implementation would still work exactly the same with a 1.x version that supports OPTIONS

With regards to round trip for validation, definitely it is possible that this does not improve roundtrip, but this is not the goal. Currently you can get a list of errors back, but those errors are only human readable, and a client can’t really do much with them. I believe having some basic data validation, will improve a client’s user experience A great deal

In a (transactional) “regular website” the browser isn’t the client - the V in the MVC / MVVM web framework running on the server is the client for the API (and that will need updating to cater for the changes you describe). The browser is just rendering the UI (HTML) generated by the client, and the UI hasn’t had a breaking change because changing the API hasn’t caused the semantics of HTML to change.

This doesn’t mean that hypermedia and HATEOAS have no value, but rather that we should recognise that they aren’t “silver bullets” either.

I wasn’t implying anything about API’s here, sorry for the confusion. I meant client, in the case of client-server applications.

No need for that - you can just define the forms under relationships.

That’s a nice distinction and I quite like that as an idea. I’m still not sold on the idea that this meta information is best provided at runtime though; and even if it is, should we be using directly in-band data to convey this, or should we link to somewhere else (e.g. API documentation :wink:) where this can be found?

I disagree. Another reason why I chose JSON API was the structured error information it provides.

Perhaps this would be more valuable where you expect to have a high proportion of novice users (e.g. a public facing API), and so you might expect the server to respond with a high proportion of rejections. The things I’m working on right now will only be available internally / to selected partners so this is less of a worry for me.

I’m wondering if it’s time to revisit this idea now that OAS 3.0 is out there and it seems to be where the world of API modeling and documentation is converging. Unlike Swagger 2.0, OAS 3.0 is able to represent jsonapi thanks to addition of some missing json-schema constructs.

I’ve been working a bit with django-restframework-json-api and it seems the DRF OPTIONS metadata would be a good place to plug this in as a proof of concept.

I still think this is a marvellous idea. Back when I started this thread I was hoping to get some community feedback on what a proper setup would be, but I have since realised, you don’t need it (the feedback I mean).

If you are working on a proof of concept congratulations :tada:
You now have an amazing project to give a talk about (at almost any tech conference since APIs are language agnostic)

If you write a blog post to share what you’ve done, please link it, I’d love to read it!

Some hidden benefits of this include:
Automatic rendering of resource “forms”
OTA(over the air) updates of resources without the need to update clients
Client side validation + single source of truth for these validations