I've been thinking a lot lately about the value of having a high-level profile for a hypermedia APIs. These are some thoughts. I should point out that I have a "Siren-centric" focus here, but I suspect such a proile, if done right, could really open things up for hypermedia APIs in general, independent of format, by providing a single source of truth about the potential resources, their properties, their actions and their relations.
The goal here is to describe a Siren API so that it can be both documented and validated. To accomplish this, the description of the API is broken into three different things being documented: resources, relations and schemas.
Ideally, the information in this description could be used to create high-level diagrams around an API that would demonstrate to users how to navigate between resources. For example, the description included in this gist could be easily translated into the following diagram:
(you can see how this diagram was created here)
The description documents the structure not only of a resources properties, but also the arguments required for its actions. This information could be used in a number of ways. For example, it could be used to synthesize types (e.g., for languages like TypeScript or Rust) used by either the client or the server. It could also be used during testing to assert that all data being exchanged conforms to the schemas in the documentation.
The expectation is that this profile information is independent of the actual resource responses. For this reason, any profile information should be pretty much invariant and can easily be cached.
The value associated with resources
is an object where each key represents a class. Each class includes
information about both the properties of that class as well as its potential actions (whether an action
is actually available would be determined by a real response). Part of the goal of this effort is to eliminate
repetitive information from responses. Much of the information about Siren actions is repeated. By documenting
it in a profile, it is no longer necessary for the server to include it in responses. of course, this means that
the client will be required to parse the profile information in order to have a complete picture of each
resource.
The relations
key documents all the relations known in the API. Furthermore, it documents each instance
where a relation can be used as an "edge" between resources. With this information one can easily visualize
how to navigate an API.
The schemas
key is used as a way to consolidate reuable schemas. The schemas can always be used inline in
the descriptions of each resource or action. But in cases where a given schema appears more than once, it
can be placed in the schemas
section so that it can be referred to via a reference (i.e.,
{ "$ref": "#/schemas/..." }
)