0

We intend to use Spring-HATEOAS to enrich our interface with hypermedia informations via HAL/JSON.

What we are wondering is, how to provide sufficient meta information of what we are going to find in a resource after following a link.

I identified different methods to publish such information, with one being the content type of the resource and the other being a profile.

However both do not allow any kind of polymorphism.

Let's assume we model a weather station which has a temperature a wind and a light sensor.
In my concept I would link those three sensors:

"item" : [
    { "href" : ".../sensors/1" } // temperature
    { "href" : ".../sensors/2" } // wind
    { "href" : ".../sensors/3" } // light
]

which means they are part of my sensor collection (which my weather station is).

To the user of my weather station, I would like to provide the meta information, that:

  1. All three sensors are sensors (which implys the existence of certain properties)
  2. Sensor 1 is a unidirectional sensor, whil 2 and 3 only measure for a specific direction
  3. Sensor 3 provides addtional to the value (intensity) some spectral information.

So in Code:

class TemperatureSensor extends Sensor
class WindSensor extends Sensor implements DirectionalSensor
class LightSensor extends Sensor implements DirectionalSensor, SprectralSensor

How can I provide those information to the user, using Spring-HATEOAS or directly HAL?

1 Answers1

1

I identified different methods to publish such information, with one being the content type of the resource and the other being a profile.

In general the media type defines how to process a payload but not necessarily what object or type its content relates to. I.e. on receiving a HTML payload you don't necessarily know that the page contains user information or the like, unless you have certain semantic annotations present within the markup. All HTML defines is a set of valid elements, how these elements have to be embedded in the payload (i.e. either <element>...</element> or <element/>), which attributes they support and when it is admissible to add which elements, i.e. certain elements such as the list-item tag <li> makes only sense as part of an unordered list <ul> or its counter-part the order list <ol>.

In regards to profiles, according to RFC 6906

A profile is defined not to alter the semantics of the resource representation itself, but to allow clients to learn about additional semantics (constraints, conventions, extensions) that are associated with the resource representation, in addition to those defined by the media type and possibly other mechanisms.

It is therefore a configuration option to set on the media-type processor, which depending on the profile specified, might apply additional validation rules, allow certain elements to appear in certain elements or the like. I.e. HTML4.01 added profiles to the <head> element so that search engines that understand this profile know that meta-information for author, date, keyword and copyright will be present which they can use directly instead of attempting to parse that information from the body directly.

HAL supports both the specification of profiles on media-type definitions as well as on link objects.

... how to provide sufficient meta information of what we are going to find in a resource after following a link.

In HTML a user is usually hinted what invoking a link might return by adding additional text, that summarizes the content of that target, or images, that express an affordance to the user, to the link context. For humans this is usually easy to understand though for an automated process such meta information are usually difficult to process and act upon. Instead of using free-text or images to express the relation the target has to the current content, link relations are used to express this.

According to RFC 8288 (Web Linking)

... an application will define the link relation type(s) it uses, along with the serialisation(s) that they might occur within. For example, the application "Web browsing" looks for the "stylesheet" link relation type in the HTML link serialisation (and optionally in the Link header field), whereas the application "AtomPub" uses the "edit" and "edit-media" link relations in the Atom serialisation.

Web linking also describes that link-relations not only describe simple semantics but also particular attributes or behaviors. More formally, they describe how the current context is related to an other resource.

Wikipedia describes link relations as:

A link relation is a descriptive attribute attached to a hyperlink in order to define the type of the link, or the relationship between the source and destination resources. The attribute can be used by automated systems, or can be presented to a user in a different way.

Such link relations should be based on standardized terms or make use of an extension mechanism, i.e. dublin-core. Microformats also lists plenty of commonly used relation names in HTML5. While link-relations must not constrain the processing of the current document or the availability of target representation types, they can specify certain behaviors or properties of target resources, i.e. that a resource supports certain HTTP methods or that support of certain media-type formats is required.

A link may have multiple different link relation names assigned. Clients that do not understand a certain link relation name should ignore it and only operate on those they do know and support. This basically just allows to add as many relation names to the URI context as needed. This is similar to the semantic Web where there may exist multiple predicates between a subject and object and further relation exist that indicate that a predicate expresses the same as an other one and may thus be used interchangingly.

HAL supports link-relations out of the box and adds CURIEs on top, which is a further reserved link-relation name itself, that hints a client on the location of a resource documentation. Link relation extension, as defined by RFC 8288, do not necessarily need to point to a documentation describing the semantics, therefore clients shouldn't access such URIs by default.

A links-section within a HAL representation response may look like this for the given problem statement:

...
"links": {
    "self": { "href": "/weatherstation" },
    "curies": [{ "name": "ws", "href": "http://api.weatherstation.com/docs/rels/{rel}", "templated": true }],
    "ws:sensors": [
        { "href": "../sensors/1", "title": "temperature"  },
        { "href": "../sensors/2", "title": "wind" },
        { "href": "../sensors/3", "title": "light" }
    ],
    "ws:unidirectional": { "href": "../sensors/1", "title": "temperature" },
    "ws:directional": [
        { "href": "../sensors/2", "title": "wind" },
        { "href": "../sensors/3", "title": "light" }
    ],
    "ws:spectral": { "href": "../sensors/3", "title": "light" },

    ...

    "http://api.weatherstation.com/rel/sensors": [
        { "href": "../sensors/1" },
        { "href": "../sensors/2" },
        { "href": "../sensors/3" }
    ],
    "http://api.weatherstation.com/rel/unidirectional": { "href": "../sensors/1" },
    "http://api.weatherstation.com/rel/directional": [
        { "href": "../sensors/2" },
        { "href": "../sensors/3" }
    ],
    "http://api.weatherstation.com/rel/spectral": { "href": "../sensors/3" }
}

At this point I'm not 100% sure whether Curies also express link-relations or just express the documentation of a resource, hence I divided the sample above a bit. In theory they should be able to be valid link-relation names itself, in which case the latter definition may be skipped, as the HAL processor will resolve them to a full URI as required by RFC 8288 anyway.

While Web linking would allow for a link-relation such as:

Link: <../sensors/3>; rel="http://api.weatherstation.com/rel/sensors http://api.weatherstation.com/rel/directional http://api.weatherstation.com/rel/spectral"

that defines all 3 attributes on the same URI, I'm not sure if this is also possible in HAL directly.

Support for Curies is documented in the reference documentation where you basically just have to add a CurieProvider bean to your config. This Curie provider kicks in on all non registered link relations you define via RelProvider. Registered link relations can easily be added via new Link("/some-target", IanaLinkRelations.NEXT) for example as documented here

Community
  • 1
  • 1
Roman Vottner
  • 12,213
  • 5
  • 46
  • 63
  • Thanks for this extensive answer. There are still some points I am unsure. [Here](https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven) Roy writes: "A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state [...]" so I was expecting a way larger impact of the media type on the system. The next word is his demand for defining new relation names and finally he requires the use of standartized relation names - so I tend to not use custom ones, when ther is any way of using standartized – derM - not here for BOT dreams Dec 05 '19 at 11:28
  • And to what I understood of the standard relation names, I should list those sensors as `items` since the weather station is basically a collection of sensors. – derM - not here for BOT dreams Dec 05 '19 at 11:30
  • So I think my problems with this concept mostly condenses in the question: 'Which part of the semantic knowledge/meta data should be transported using which technique?' In researching the internet, you mostly find, what you should not do, while hardly anything that you should do - where no-on claims, that this is wrong. – derM - not here for BOT dreams Dec 05 '19 at 11:33
  • @derM The actual issue is, that there are, except for the Web itself, not so many true REST architectures out there and people obviously need some reference implementations to copy from. Most of those so called "REST APIs" don't understand REST actually and just map their RPC approach onto the HTTP domain, which has just the same outcomes as traditional RPC styles, such as SOAP, RMI or CORBA. In regards to link relation, you can add `item` link relations for entries if you think they are part of a collection and also include link relation that advertise such URIs as sensors or other things – Roman Vottner Dec 05 '19 at 11:49
  • @derM In regards to media-types, they are important, don't get me wrong. Without it you won't be able to interpret the data to start with. The problem with most APIs out there is, that they assume a media-type to represent something like an object description, which it is not. It should be as general as possible to allow reusability. Further, Fielding claimed that REST shouldn't have [typed resources meaningful to clients](http://soabits.blogspot.com/2012/04/restful-resources-are-not-typed.html) but instead rely on content-type negotiation. – Roman Vottner Dec 05 '19 at 12:06
  • 1
    @derM A media-type itself is at its core just a human-readable description of how to process the data, i.e. [text/html](https://tools.ietf.org/html/rfc2854), which refers to the actual spec ([4.01](https://www.w3.org/TR/html401/) in that case, though [HTML](https://www.w3.org/TR/html52/) [evolves further](https://www.w3.org/TR/html53/)) to explain the remaining syntax and semantics of the respective elements. It may also define link-relations, as HTML does with stylesheets or HAL does with curies. So it is important – Roman Vottner Dec 05 '19 at 12:10