使用 HAL 提供有关 link 目标内容的信息

Providing information ragarding the content of a link target with HAL

我们打算使用 Spring-HATEOAS 通过 HAL/JSON 来丰富我们与超媒体信息的界面。

我们想知道的是,如何在遵循 link.

后提供我们将在资源中找到的内容的足够元信息

我确定了发布此类信息的不同方法,一种是资源的内容类型,另一种是配置文件。

但是两者都不允许任何类型的多态性。

假设我们为一个气象站建模,该气象站具有温度、风和光传感器。
在我的概念中,我会 link 这三个传感器:

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

这意味着它们是我的传感器集合的一部分(我的气象站是)。

对于我的气象站的用户,我想提供元信息,即:

  1. 三个传感器都是传感器(暗示一定属性的存在)
  2. 传感器1是单向传感器,而2和3只测量特定方向
  3. 传感器 3 提供附加值(强度)一些光谱信息。

所以在代码中:

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

如何使用 Spring-HATEOAS 或直接 HAL 向用户提供这些信息?

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

一般来说,媒体类型定义了如何处理有效负载,但不一定定义其内容与什么对象或类型相关。 IE。在收到 HTML 有效载荷时,您不一定知道该页面包含用户信息等,除非您在标记中包含某些语义注释。所有 HTML 定义的是一组有效元素,这些元素必须如何嵌入到有效负载中(即 <element>...</element><element/>),它们支持哪些属性以及何时允许添加哪些元素,即某些元素,例如列表项标签 <li> 仅作为无序列表 <ul> 或其对应部分订单列表 <ol>.[=37 的一部分才有意义=]

关于配置文件,根据 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.

因此,这是在媒体类型处理器上设置的配置选项,根据指定的配置文件,它可能会应用额外的验证规则,允许某些元素出现在某些元素中等。 IE。 HTML4.01 将配置文件添加到 <head> 元素,以便理解此配置文件的搜索引擎知道 authordatekeyword 和 [=21] 的元信息=] 将出现,他们可以直接使用,而不是试图直接从正文中解析该信息。

HAL 支持 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.

在 HTML 中,通常会提示用户调用 link 可能会 return 通过添加额外的文本来总结该目标的内容,或图像来表达可供性给用户,给 link 上下文。对于人类而言,这通常很容易理解,但对于自动化过程而言,此类元信息通常难以处理和采取行动。不是使用自由文本或图像来表达目标与当前内容的关系,而是使用 link 关系来表达这一点。

根据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 还描述了 link-关系不仅描述了简单的语义,还描述了特定的属性或行为。更正式地说,它们描述了当前上下文如何与其他资源相关。

Wikipedia 将 link 关系描述为:

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.

这样的link关系应该基于standardized terms or make use of an extension mechanism, i.e. dublin-core. MicroformatsHTML5中也列出了很多常用的关系名。虽然 link 关系不能限制当前文档的处理或目标表示类型的可用性,但它们可以指定目标资源的某些行为或属性,即资源支持某些 HTTP 方法或支持某些媒体-type 格式是必需的。

A link 可能分配了多个不同的 link 关系名称。不理解某个 link 关系名称的客户应该忽略它,只对他们知道和支持的关系进行操作。这基本上只允许根据需要向 URI 上下文添加尽可能多的关系名称。这类似于语义网,其中一个主语和宾语之间可能存在多个谓词,并且存在进一步的关系,表明一个谓词表达与另一个谓词相同,因此可以互换使用。

HAL 支持开箱即用的 link-关系,并在顶部添加 CURIE,这是进一步保留的 link-关系名称本身,提示客户端资源文档的位置. Link RFC 8288 定义的关系扩展不一定需要指向描述语义的文档,因此默认情况下客户端不应访问此类 URI。

对于给定的问题陈述,HAL 表示响应中的 links 部分可能如下所示:

...
"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" }
}

在这一点上,我不是 100% 确定 Curies 是否也表达了 link-关系,或者只是表达了资源的文档,因此我将上面的示例稍微分开了。从理论上讲,它们应该能够成为有效的 link-关系名称本身,在这种情况下,可以跳过后一个定义,因为 HAL 处理器无论如何都会按照 RFC 8288 的要求将它们解析为完整的 URI。

虽然 Web linking 允许 link-关系,例如:

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

在同一个 URI 上定义所有 3 个属性,我不确定这是否也可以直接在 HAL 中实现。

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

中记录了对 Curies 的支持