Hydra is a lightweight vocabulary to create hypermedia-driven Web APIs. By specifying a number of concepts commonly used in Web APIs it enables the creation of generic API clients.
This specification was published by the Hydra W3C Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.
To participate in the development of this specification, please join the Hydra W3C Community Group. If you have questions, want to suggest a feature, or raise an issue, please send a mail to the [email protected] mailing list.
Coping with the ever-increasing amount of data becomes increasingly challenging. To alleviate the information overload put on people, systems are progressively being connected directly to each other. They exchange, analyze, and manipulate humongous amounts of data without any human interaction. Most current solutions, however, do not exploit the whole potential of the architecture of the World Wide Web and completely ignore the possibilities offered by Linked Data technologies.
The combination of the REST architectural style and the Linked Data principles offer opportunities to advance the Web of machines in a similar way that hypertext did for the human Web. Most building blocks exist already and are in place but they are rarely used together. Hydra tries to fill that gap. It allows data to be enriched with machine-readable affordances which enable interaction. This not only addresses the problem that Linked Data is still mostly read-only, but it also paves the way for a completely new breed of interoperable Web APIs. The fact that it enables the creation of composable contracts means that interaction models of Web APIs can be reused at an unprecedented granularity.
This specification describes the conformance criteria for Hydra API documentations and Hydra clients. This criteria is relevant to authors, authoring tool implementers, and client implementers. All authoring guidelines, diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked as non-normative. Everything else in this specification is normative.
Conformance for Hydra clients should probably not be specified in this document.
Add normative statements
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this specification have the meaning defined in [[!RFC2119]].
The basic idea behind Hydra is to provide a vocabulary which enables a server to advertise valid state transitions to a client. A client can then use this information to construct HTTP requests which modify the server’s state so that a certain desired goal is achieved. Since all the information about the valid state transitions is exchanged in a machine-processable way at runtime instead of being hardcoded into the client at design time, clients can be decoupled from the server and adapt to changes more easily.
The figure below illustrates the Hydra core vocabulary (the figure’s intention is to show how Hydra is used rather than its precise definition).
Is this illustration clear enough or is it confusing? Feedback would be much appreciated.
Add ranges for Operation "members"
An alphabetical index of the classes and properties of Hydra is given below. All the terms are hyperlinked to their detailed description for quick reference.
The used prefixes should be documented somewhere.
Throughout this section, a simple Web API featuring an issue tracker will be used to illustrate how Hydra can be used. The Web API enables its users to file new issues, modify or delete existing ones, and to comment them. For the sake of simplicity, orthogonal aspects such as authentication or authorization are not covered.
The exemplary Web API has to expose representations of issues and comments. To enable interaction with those resources, a client has to know which operations the server supports. In human-facing websites such affordances are typically exposed by links and forms and described in natural language. Unfortunately, machines can not interpret such information easily. The solution that presents itself is to reduce the language to a small number of unambiguous concepts which are easily recognizable by a machine client. Hydra formalizes such concepts.
The simplest and most important affordance on the Web are hyperlinks. Without them, it would be impossible to browse the Web. Users typically select the link based on the text it is labeled with. To give machines a similar understanding, links can be annotated with a link relation type—a registered token or a URI identifying the semantics of the link. The following example shows how such a typed link is used in HTML to reference a stylesheet.
In Linked Data, the link relation type corresponds to the property itself. An example in JSON-LD would thus look as follows.
Generally, a client decides whether to follow a link or not based on
the link relation (or the property in general, in the case of
Linked Data) which defines its semantics. There are however also
clients such as Web crawlers which simply follow every which is
intended to be dereferenced. In HTML this usually means that all
links in anchor elements (the
<a> tag) are
followed but, e.g., most references in link elements (the
<link> tag), such as used in the example above,
are ignored. Since in RDF serializations no such distinction exists,
the best a client can do is to blindly try to dereference all URIs.
It would thus be beneficial to describe in a machine-readable manner
whether a property represents a link that is intended to be
dereferenced or whether it solely represents an identifier. Hydra's
Link class does just that. It can be used to define properties
that represent dereferenceable links. In the exemplary Web API used
throughout this section, it can, e.g., be used to define a property
linking issues to their comments:
In the example above, a property identified with the URL
http://api.example.com/vocab#comments is defined to be
of the type Link. This is enough information for a client
understanding Hydra to know that the value of the
comments property in the following example is intended
to be dereferenced.
In the example above, the value of the
property is a JSON object with an
@id member. This is
JSON-LD's convention to distinguish between strings and IRIs. By
using JSON-LD's type-coercion feature, the representation can be
made even more idiomatic:
While links are enough to build read-only Web APIs, more powerful affordances are required to build read-write Web APIs. Thus, Hydra introduces the notion of operations. Simply speaking, an Operation represents the information necessary for a client to construct valid HTTP requests in order to manipulate the server's resource state. As such, the only required property of an Operation is its HTTP method. Optionally, it is also possible to describe what information the server expects or returns, including additional information about HTTP status codes that might be returned. This helps a developer to understand what to expect when invoking an operation. This information has, however, not to be considered as being complete; it is merely a hint. Developers should, e.g., expect that other HTTP status codes might be returned and program their clients accordingly.
Hydra has three predefined operation classes, namely CreateResourceOperation, ReplaceResourceOperation, and DeleteResourceOperation. As their names suggest, they can be used to implement simple CRUD functionality. More specialized operations can be easily created by subclassing these classes or their base class Operation.
The following example illustrates how representations can be augmented with information that enables clients to interact with them. A client would be able to understand that the resource in the example below can be deleted by sending an HTTP DELETE request.
The example above references Hydra's context to map properties such
method and values like
DeleteResourceOperation to URLs that unambiguously
identify these concepts. It would be similarly valid JSON-LD if
these mappings would be directly embedded into the representation
or if the full URLs would be used instead. Typically, however, the
context is the same for a lot of representations in a Web API and
it thus makes sense to reduce the response size by leveraging a
remote context that can easily be cached by a client.
In Web APIs, most representations are typically very similar. Furthermore, resources often support the same operations. It thus makes sense, to collect this information in a central documentation. Traditionally, this has been done in natural language which forces developers to hardcode that knowledge into their clients. Hydra addresses this issue by making the documentation completely machine-processable. The fact that all definitions can be identified by URLs enables reuse at unprecedented granularity.
Hydra's ApiDocumentation class builds the foundation for the description of a Web API. As shown in the following example, Hydra describes a API by giving it a title, a short description, and documenting its main entry point. Furthermore, the classes known to be supported by the Web API and additional information about status codes that might be returned can be documented. This information may be used to automatically generate documentations in natural language.
In Linked Data, properties are, just as everything else, identified by IRIs and thus have global scope which implies that they have independent semantics. In contrast, properties in data models as used in common programming languages are class-dependent. Their semantics depend on the class they belong to. In data models classes are typically described by the properties they expose whereas in Linked Data properties define to which classes they belong. If no class is specified, it is assumed that a property may apply to every class.
These differences have interesting consequences. For example, the commonly asked question of which properties can be applied to an instance of a specific class can typically not be answered for Linked Data. Strictly speaking, any property which is not explicitly forbidden could be applied. This stems from the fact that Linked Data works under an open-world assumption whereas data models used by programmers typically work under a closed-world assumption. The difference is that when a closed world is assumed, everything that is not known to be true is false or vice-versa. With an open-world assumption the failure to derive a fact does not automatically imply the opposite; it embraces the fact that the knowledge is incomplete.
Mention that Hydra classes are dereferenceable resources.
Since Hydra uses classes to describe the information expected or returned by an operation, it also defines a concept to describe the properties known to be supported by a class. The following example illustrates this feature. Instead of referencing properties directly, supportedProperty references an intermediate data structure, namely instances of the SupportedProperty class. This makes it possible to define whether a specific property is required or whether it is read-only or write-only depending on the class it is associated with.
All instances of a specific class typically support the same operations. Hydra therefore features a supportedOperation property which defines the operations supported by all instances of a class.
The same feature can be used to describe the operations supported by values of a Link property. This is often helpful when certain operations depend on the permissions of the current user. It makes it, e.g., possible to show a "delete" link only if the current user has the permission to delete the resource. Otherwise, the link would simply be hidden in the representation.
Describe the various properties of an operation.
The first step when trying to access a Web API is to find an entry
point. Typically, this is done by looking for documentation on the
API publisher's homepage. Hydra enables the API's main entry point
to be discovered automatically if the API publisher marks his
responses with a special HTTP Link Header as defined in [[RFC5988]].
A Hydra client would look for a Link Header with a relation type
http://www.w3.org/ns/hydra/core#apiDocumentation (this is
the IRI identifying the hydra:apiDocumentation property).
In the following example, a Hydra client simply accesses the
homepage of an API publisher (
to find the entry point of its API. A client may use an HTTP GET or
HEAD request. The difference between the two is that the former may
return a message-body in the response whereas the latter will not;
otherwise they are identical.
The response in the example above contains an HTTP Link Header
Retrieving that resource, the client would obtain a
Hydra API documentation defining the API's main entry
Please note that in most cases the entry point will already be known to the client. Thus, the discovery of the API documentation using HTTP Link Headers is typically not necessary as the concepts used in responses from the API will dereference to their documentation.
Describe Hydra's Resource class? Or should that better be described somewhere in the beginning?
In many situations, it makes sense to expose resources that reference a set of somehow related resources. Results of a search query or entries of an address book are just two examples. To simplify such use cases, Hydra defines the two classes hydra:Collection and hydra:PagedCollection.
A hydra:Collection can be used to reference a set of resources as follows:
As shown in the example above, member items can either consist of solely a link or also include some properties. In some cases embedding member properties directly in the collection is beneficial as it may reduce the number of HTTP requests necessary to get enough information to process the result.
Since collections may become very large, Web APIs often chose to split a collection into multiple pages. In Hydra, that can be achieved with a hydra:PagedCollection. In addition to the member property, a PagedCollection may also include links to the firstPage, nextPage, previousPage, or lastPage as well as information about the itemsPerPage and the totalItems as shown in the following example.
Say that all these properties are optional? What about firstPage and, more interestingly, lastPage?
Sometimes, it is impossible for a server to construct a URL because the URL depends on information only known by the client. A typical use case are URLs which enable a client to query the server. In such a case, the server cannot construct the URL because it does not know the query the client is interested in. What the server can do however, is to give the client a template to construct such a URL at runtime. In Hydra, the IriTemplate class is used to do so.
A IriTemplate consists of a template, whose syntax is specified in [[!RFC6570]], and a set of mappings. Each IriTemplateMapping maps a variable used in the template to a property and may optionally specify whether that variable is required or not.
The example above maps the variable
q to Hydra's
freetextQuery property and marks it as required.
As its name suggests, the freetextQuery property can be used
for free text queries.
Similar to how Hydra's Link class allows the definition of properties that represent hyperlinks as described in , the TemplatedLink class allows the definition of properties whose value are IRI templates. Hydra predefines one such property, namely the search property which can be used to document available search interfaces.
HTTP status codes have well defined semantics and can be used to
signal the outcome of an operation. Unfortunately, however, HTTP
status codes by themselves are often not specific enough, making it
difficult to understand the real cause of an error. For
429 Too Many Requests response is rarely
informative enough by itself. The address this issue, Hydra defines
a StatusCodeDescription class which allows additional
information to be associated with an HTTP status code.
An ApiDocumentation or an Operation may document the status codes that might be returned by the server using the statusCodes property as described in . This allows a developer to understand what to expect when invoking an operation. It has, however, not to be considered as an extensive list of all potentially returned status codes; it is merely a hint. Developers should expect to encounter other HTTP status codes as well.
A server may also return a StatusCodeDescription directly in a response. When doing so, it often makes sense to subclass the StatusCodeDescription to make its semantics more explicit. Hydra defines just one such subclass, namely the Error class. This provides an extensible framework to communicate error details to a client.
The authors would like to thank the following individuals for contributing their ideas and providing feedback for writing this specification: Arnau Siches, Mark Baker, Matthias Lehmann, Ruben Verborgh, Ryan J. McDonough, Sam Goto, Thomas Hoppe, @wasabiwimp (on GitHub).