We are considering the use of the RFC5988 Link header in out HTTP requests. I’m interested in the community’s thoughts on this.
The use case (minus the specific details, sorry) is as follows. The REST API in question is part of what is essentially a business logic application server that performs provisioning operations in various network elements of a customer’s network. The resources it’s acting on may reside on one of several servers in that network. The API aims to abstract this away, resolving the target server automatically.
Unfortunately, there are use cases where the server is unable to resolve the target server automatically. These are cases where legacy functionality is being used, that is incapable of the automatic resolution. They’re not intended to exist long term… but you know how it goes.
Fortunately, in these scenarios, the API client already knows the ID of the target server. This presents us with a solution: we can let the client tell us what server the resource resides on.
I’ve looked at several options, described below, and we’ve settled on the idea of having the client provide the information via a Link header. This doesn’t really seem to fit with the designed purpose of this header (as I understand it).
Alternatives:
Just don’t do it. If the API is not supposed to expose the fact that resources might reside on one of several servers, then, don’t expose it.
I wish this was an option for us :) It isn’t.
Expose it, via the resource URI. If you’re going to expose the fact that resources may be on one of several servers, be explicit about it in the URI. So instead of:
DELETE /api/resourceType/{+resourceId}
… you have:
DELETE /api/servers/{+serverId}/resourceType/{+resourceId}
This presents multiple issues. First, our long-term API design does NOT want to expose this. Further, some of our resources are composite - internally (hidden from the client), they may be composed of 2 resources on 2 totally different network elements. Putting /servers/{+serverId} in the URI limits us to allowing the client to specify the target server for only one type of network element.
Expose it, via the request body.
This doesn’t work for requests with no body - GET, DELETE, etc.
Expose it, via a URI query parameter, e.g. add an optional “{?serverId}” on every request URI.
First, to me, this just smells bad… but that’s not reason enough.
Further, what this does is make every resource be addressable by more than one URI - either with, or without, the ?server parameter.
It is, however, probably the simplest solution, from both the client and server perspective.
Embed it in the resource ID. For example, instead of:
/api/resourceType/foo
you would have:
/api/resourceType/server1-foo
This is technically possible; however, our resource IDs are server-generated, and the ID (the whole URI) is supposed to be opaque to the client. We explicitly do NOT want clients trying to gather several pieces of information and construct the resource ID for a request themselves. Thus, this option is not a viable way to enable the client to tell us what server a resource is on.
Expose it, via an optional Link header on every request. So a client can optionally include, on any request, something like this:
Link: <http://api.example.com/api/network-elements/someElementType/{+serverId}>;rel="http://api.example.com/rels/someElementTypeId"
This allows us a client to optionally provide this information, in any request… without compromising the long-term goals of our API design (and also without a lot of code change, which is a bonus).
What’s your gut feel, about the idea of using a Link header in the request this way? If it seems wrong to you, why - and, do you have other suggestions?
(my only other thought so far is to use an application-specific header, which we haven’t really explored, since Link headers seem to fit the bill).
Neil.
--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.