为了简单起见并避免命名冲突,我一直在像这样在我的记录资源中捆绑链接...
{
id: 211,
first_name: 'John',
last_name: 'Lock',
_links: [
{ rel: 'self', href: 'htttp://example.com/people/211' }
]
}
但是,我不知道如何在集合中实现链接。我花了很长时间在网上搜索示例,而不是使用不太精简的 HAL。我无法解决我的问题。
[
{id:1,first_name:.....},
{id:2,first_name:.....},
{id:3,first_name:.....},
"_links": "Cant put a key value pair here because its an-array"
]
这意味着我必须将数组包装在一个容器对象中。
{
people: [ {id:1,first_name:.....} ],
links: [ { rel:parent, href:.... ]
}
但它与单一资源不同,所以我要让记录表现得像集合一样,并将其包装在一个容器中......
{
person: {
id: 211,
first_name: 'John',
last_name: 'Lock'
},
links:[
{ rel: 'self', href: 'htttp://example.com/people/211' }
]
}
从表面上看,这似乎是一个非常巧妙的解决方案。生成的 JSON 更深一层,但 HATEOAS 已经实现,所以没问题吧?一点也不。当我回到收藏品时,真正的刺痛来了。现在单个资源已经被包装在一个容器中以便与集合保持一致,现在必须更改集合以反射(reflect)更改。这就是它变得丑陋的地方。十分难看。现在集合看起来像这样......
{
"people": [
{
"person": {
....
},
"links" : [
{
"rel": "self",
"href": "http://example.com/people/1"
}
]
},
{
"person": {
....
},
"links" : [
{
"rel": "self",
"href": "http://example.com/people/2"
}
]
}
],
"links" : [
{
"rel": "self",
"href": "http://example.com/people"
}
]
}
是否有更简单的解决方案来为集合实现 HATEOAS?或者我应该和 HATEOAS 告别,因为它迫使我过度复杂化数据结构?
最佳答案
请不要仅仅因为 HAL 看起来有点臃肿(以 JSON 形式,它非常小)就这么快就将其关闭。
HAL 之于 JSON 就像 HTML 之于纯文本。
它添加了超链接。 REST 需要超链接和普遍理解的表示格式(例如 HAL 或 Collection+JSON)。您还需要 HATEOAS 来实现 REST,没有 HATEOAS 就不是 REST! HATEOAS 当然需要超链接。
在您的情况下,您正在尝试构建一个集合资源。 IANA-registered relation因为那是“项目”(具有反向关系“集合”)。以下是 HAL 中 People 集合的表示:
{
"_links": {
"self": { "href": "http://example.com/people" },
"item": [
{ "href": "http://example.com/people/1", "title": "John Smith" },
{ "href": "http://example.com/people/2", "title": "Jane Smith" }
]
},
"_embedded": {
"http://example.com/rels#person": [
{
"first_name": "John",
"last_name": "Smith",
"_links": {
"self": { "href": "http://example.com/people/1" },
"http://example.com/rels#spouse": { "href": "http://example.com/people/2" }
}
},
{
"first_name": "Jane",
"last_name": "Smith",
"_links": {
"self": { "href": "http://example.com/people/2" },
"http://example.com/rels#spouse": { "href": "http://example.com/people/1" }
}
}
]
}
}
注意:
此集合的主要数据来自 _links.item[]
。这些是集合中的项目。 _embedded
数组中提供了每个项目的完整(或至少一些附加)数据。如果客户端需要这些额外的数据,它必须通过为每个 n
搜索 _embedded[n]._links.self.href
来找到它们。这是 HAL 的设计约束。其他超媒体表示格式也有类似的限制(尽管可能会朝另一个方向发展)。
我为 item
数组的每个成员添加了一个 title
值。如果呈现为 HTML,它可以出现在开始和结束 anchor 标记之间,或者作为客户端中菜单项的文本,无需客户端进一步处理表示。
没有 ID 参数。所有对其他资源的引用都显示为超链接。客户端不必通过在某个预定义位置将 ID 粘贴到 URL 中来“构建”URL。这构成了禁止对客户端和服务器进行独立更改的带外信息。
所有超链接都应该是绝对的,因为相对 URL 可能会导致问题。您的所有关系都应该列在该 IANA 页面上,或者使用 URI 来定义它们。理想情况下,该 URI 应该是一个可取消引用的 HTTP URL,并在另一端包含有关关系的文档。
https://stackoverflow.com/questions/17877220/