I am in the middle of developing my first Hypermedia API. I thought I had a good grasp of things but when It comes to documenting the API, I start to question my understanding of the whole concept.
The core of the question comes down to documention, but It might be that I did not understand one or more aspects correctly. If so, please tell me :-)
Documenting Link Relations
Let's say I have a more or less generic link relation (https://example.com/rels/accounts
) in my API to link related accounts. The exact meaning can change on context, right?
- On my billboard (or index), I might have a link with that relation to browse all accounts.
- On another resource, account group for example, it might just link to a specific subset of accounts belonging to that group.
How should I document that relation? Just saying that this is a link to a collection of accounts seems not enough. However, that is exactly what RFC5988 does, just describing what the link itself means. So that might be the way to go.
The problem gets worse with actual state transitions. Let's use https://example.com/rels/create-account
as our example here. If the documentation just says "This is where you create a new account", It makes no statements on what I have to do with that link to create a resource. Where would the documentation be that states something along the lines:
You either POST multipart/form-data or application/json to this endpoint that contains at least the following fields [...]
The relation itself does not seem to be the right place. Especially when you consider that the payload to that URL might also change on context. In our example, having that relation on an account group would make it mandatory to omit the accountGroup field because the value is provided by the context.
Documenting Profiles
As far as I understood it, I can (and probably should) have a profile for each resource in my API, documenting the resource itself. This would include its properties and links that can occur. Would that be the place where I specify what the link means exactly?
Sticking to my earlier example, would I document for profile https://example.com/profiles/account-group
that the link with the relation https://example.com/rels/accounts
links to a collection of accounts that are part of this group?
That makes sense to me, but when we go into actual state transitions things seem to get messy.
State transitions
Let's say the client navigated to an account collection from an account group. The resource itself would not really differ from the resource that contains all global accounts. It would have pagination links and the links to the account resources themselves.
If that account-collection resource has a link with the relation type https://example.com/rel/create-account
I would be in deep trouble, right? Because the information that this is an account-collection containing just accounts of a certain group is not encoded in the profile
https://example.com/profiles/account-collection
and can therefore not contain the information that clients have to omit the accountGroup property when posting to that resource.
Concrete Questions
- Am I right that relations definitions should be weak and not contain any information about how I can interact with the resource it links to?
- If so, can I expect from client to follow a link and then discover what they can do, based on the profile of that resource. This seems wrong, especially for state transitions.
- If profiles should document what a client might do with the linked resources, I cannot transport context across multiple "jumps" within the API, correct?
- Should I use even more profiles and relations?
https://example.com/profiles/global-accounts
andhttps://example.com/profiles/account-group-accounts
come to mind.
The more I think about it, I must either miss a critical piece or it's something that can be solved in multiple ways. Because of that, I am aware that there might be no 100%-correct answer to this question. But maybe someone can enlighten me so that I can make my own trade-offs? :)