h:link is a super-set of h:ref allowing representation of complex hyperlinks and parametrized actions (similar to HTML’s Form element).
h:link points to an array of objects, where the order of such links should not be considered significant.
Each object can have following properties of predefined semantic meaning:
required. A URI [RFC7320] or URI Template [RFC6570], or a CURIE which expands into a URI or URI Template.
optional. If this field is present, the value of the uri field should be treated as a URI Template [RFC6570] after any CURIE expansion. When present, the template attribute is an object containing the following properties:
contentType
- a media-type that should be used to encode fields
into, to satisfy the construction of a request.
E.g. “application/x-www-form-urlencoded”fields
- an objects that explains what data
elements should be submitted to the endpoint represented by uri
. Each
key is the name of the variable to be sent. If variables are going both
in URI template and in the body of the request, and disambiguiation is
required choose names sensibly to avoid conflicts. Each field object
can have following properties:
label
: optional. Hint for human-friendly label to present to humans,
if an input form is rendered.required
: optional. Whether a value is required. Boolean true/false.
Default: true.type
: optional. One of: “text”, “number”, “date”, “hidden” or “boolean”.
Defaults to “text”.default
: optional. Default value.pattern
: optional. Restrictions on allowed values. Syntax must be the
same as used in pattern in HTML5Required. An array of link relation types per RFC8288. Only IANA-registered link relation types SHOULD be refered to by simple names, all application-specific and non-common link relation types should be URIs (usually CURIEed, to save space). The order of the link relations in this array should not be considerd significant.
optional. String. Usually human-readable, for presentation hints.
optional. Suggests to the consumer whether the resource from the URI SHOULD be
embedded within the currently loaded document or treated as a transition to a
new state/document (embed=”false”). Defaults to false. Unrecognized values
should also be treated as false
.
Expected values include the folowing list:
false
: do not embed.true
: embed using the best-effort approach. SHOULD use the content-type
headers returned by the resource to determine media type of the resource
being embedded.image/*
: embed as imageaudio/*
: embed as audiovideo/*
: embed as videotext/*
: embed as textOptional. String. Indicates the action represented by the uri transition. Hyper borrows definitions of possible action types from UBER and the list of valid values is as follows:
append
: An unsafe, non-idempotent request to add a new item. (e.g HTTP POST)partial
: An unsafe, non-idempotent request to modify parts of an existing item. (e.g. HTTP PATCH)read
: A safe, idempotent request. [DEFAULT] (e.g. HTTP GET)remove
: An unsafe, idempotent request to delete an existing item. (e.g. HTTP DELETE)replace
: An unsafe, idempotent request to replace an existing item. (e.g. HTTP PUT){
"h:link": [{
"uri" : "http://api.example.com/users/{user}/?x={xval}&y=foo",
"action" : "append",
"template" : {
"contentType" : "application/json",
"fields" : {
"user" : {"pattern" : "[a-z0-9_-]"},
"xval" : {"type" : "number"},
"firstName" : {}, "lastName" : {},
"role" : {"required" : false}
}
}
}]
}
Please note that “user” and “xval” fill-in values in the URI template, whereas “firstname”, “lastname” and “role” are going to be transmitted as JSON HTTP POST Body elements.
As noted earlier, h:link is a superset of h:ref, any h:ref can actually be represented as an h:link. Case in point: the earlier example of h:ref, when represented as h:link would look as follows:
{
"h:head" {
"title" : "Employees of North-East Department"
},
"department" : {
"h:value" : "north-east",
"h:label" : "North-East",
"h:link" : [{"uri" : "http://api.example.com/departments/1234", "rel": ["about"]}]
},
"employees" : [
],
"h:link" : [
{"rel": ["self"], "uri" : "http://api.example.com/users?dep=1234&page=4"},
{"rel": ["next"], "uri" : "http://api.example.com/users?dep=1234&page=5"},
{"rel": ["prev"], "uri" : "http://api.example.com/users?dep=1234&page=3"},
{"rel": ["first"], "uri" : "http://api.example.com/users?dep=1234&page=1"},
{"rel": ["last"], "uri" : "http://api.example.com/users?dep=1234&page=10"}
]
}
As you can see, using h:link
for simple references (single rel and a URI
accessed via HTTP GET) is a bit more involved than just using h:ref, which is
exactly why h:ref
exists: to make easy cases easy. A lot of links are simple.
The “next”, “prev”, “first”, “last” and “self” links, used for pagination being
most common examples. We decided that for easy cases there should be an easy
solution. That said, since h:link is a perfect superset of h:ref, you can write
all your Hyper documents without ever using h:ref, using h:link instead, and
they will still be perfectly valid.