RESTful JSON集合应如何实现HATEOAS样式的链接? [英] How should HATEOAS-style links be implemented for RESTful JSON collections?

查看:102
本文介绍了RESTful JSON集合应如何实现HATEOAS样式的链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为使事情变得简单并避免命名冲突,我一直在这样的记录资源中捆绑链接...

To keep things simple and to avoid nameing collisions, I've been bundling links in my record resources like this...

{
    id: 211,
    first_name: 'John',
    last_name: 'Lock',
    _links: [
        { rel: 'self', href: 'htttp://example.com/people/211' }
    ]
}

但是,我不知道如何实现集合中的链接.我花了很长时间在网上搜寻示例,而不是使用不太精巧的 HAL ,我无法调和我的问题.

However, I can't work out how to implement links in collections. I have spent a long time trawling around the web for examples and other than using the not so lean HAL I'm unable to reconcile my problem.

[
    {id:1,first_name:.....},
    {id:2,first_name:.....},
    {id:3,first_name:.....}, 
    "_links": "Cant put a key value pair here because its an-array" 
]

这意味着我必须将数组包装在一个容器对象中.

Which means I have to wrap up the array in a container object.

[
    people: [ {id:1,first_name:.....} ],
    links: [ { rel:parent, href:.... ]
]

但是与单一资源不同,因此我将使记录的行为像集合一样,并将其包装在容器中....

But is is different to the singular resource so I'm going to make the record behave like the collection and wrap it up in a container....

{
    person: {
        id: 211,
        first_name: 'John',
        last_name: 'Lock',
        _links: 
    },
    links:[
        { rel: 'self', href: 'htttp://example.com/people/211' }
    ] 
}

从表面上看,这似乎是一个很好的解决方案.生成的JSON更深一层,但是已经实现了HATEOAS,所以还好吗?一点也不.当我回到收藏中时,真正的刺痛就来了.既然已经将单个资源包装在容器中以便与集合保持一致,那么现在必须更改集合以反映所做的更改.这就是丑陋的地方.十分难看.现在集合看起来像这样……

On the surface this seems like quite a neat solution. The resulting JSON is one level deeper but HATEOAS has been implemented, so that's all good right? Not at all. The real sting comes when I go back to the collection. Now that the single resource has been wrapped up in a container in order to be consistent with the collection, the collection must now be changed in order to reflect the changes. And this is where it gets ugly. Very ugly. Now the collection looks like this...

{
    "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告别,迫使我过度复杂化数据结构?

Is there a simpler solution to implementing HATEOAS for collections? Or should I kiss HATEOAS goodbye for forcing me to over complicate the data structure?

推荐答案

请不要因为HAL看起来有点肿(以JSON形式,它非常小)而迅速关闭HAL.

Please don't dismiss HAL so quickly just because it looks a little bloated (in its JSON form, it's quite minimal).

HAL是JSON,HTML是纯文本.

它添加超链接.您需要REST的超链接和通常理解的表示格式(例如HAL或Collection + JSON).您还需要HATEOAS for REST,而没有HATEOAS则不是REST! HATEOAS当然需要超链接.

It adds hyperlinks. You need hyperlinks and a commonly understood representation format (such as HAL or Collection+JSON) for REST. You also need HATEOAS for REST, without HATEOAS it isn't REST! HATEOAS requires hyperlinks of course.

在您的情况下,您正在尝试构建集合资源. IANA注册的关系是"item"(带有反向关系集合").这是People集合在HAL中的表示形式:

In your case, you are trying to build a collection resource. The IANA-registered relation for that is "item" (with reverse relation "collection"). Here is the representation in HAL for a People collection:

{
    "_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数组中提供了每个项目的完整(或至少一些其他)数据.如果客户端需要这些附加数据,则它必须通过在_embedded[n]._links.self.href中搜索每个n来找到它们.这是HAL的设计约束.其他超媒体表示形式格式也有类似的约束条件(尽管可能会朝另一个方向发展).

  • The primary data for this collection comes from _links.item[]. These are the items in the collection. The full (or at least some additional) data for each item is available in the _embedded array. If the client needs these additional data, it must find them by searching through _embedded[n]._links.self.href for each n. This is a design constraint of HAL. Other hypermedia representation formats have similar constraints (though perhaps going in the other direction).

我为item数组的每个成员添加了title值.如果呈现为HTML,则它可以显示在开始和结束锚标记之间,或者作为客户端中菜单项的文本出现,而无需客户端进一步处理表示形式.

I have added a title value for each member of the item array. This can appear between the opening and closing anchor tags if rendering to HTML, or as the text of a menu item in the client, without need for further processing of the representation by the client.

没有ID参数.所有对其他资源的引用都以超链接的形式公开.客户端不必通过在某个预定义位置将ID粘贴到URL中来构建" URL.这构成了带外信息,阻止了对客户端和服务器的独立更改.

There are no ID parameters. All references to other resources are exposed as hyperlinks. A client should not have to "build" a URL by gluing an ID into a URL at some pre-defined place. This constitutes out-of-band information which inhibits independent changes to the client and server.

您的所有超链接都应该是绝对的,因为相对URL可能会引起问题.您的所有关系都应在该IANA页面上列出,或使用URI进行定义.理想情况下,该URI应该是可取消引用的HTTP URL,并在另一端提供有关该关系的文档.

All of your hyperlinks should be absolute, since relative URLs may cause problems. All of your relations should be either listed on that IANA page or use a URI to define them. Ideally, that URI should be a dereferencable HTTP URL with documentation about the relation at the other end.

这篇关于RESTful JSON集合应如何实现HATEOAS样式的链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆