JSON表示中的链接关系

时间:2011-08-09 08:26:14

标签: json rest hateoas

我正在设计一个基于JSON表示的RESTful API。为了遵守HATEOAS,我广泛使用资源之间的链接。因此,我跟着this suggestion以非常类似于ATOM链接的方式序列化链接。

现在我有时会发现识别正确链接关系类型的问题。当资源包含指向自身的链接时,self关系是显而易见的。当资源是子资源的集合和聚合,或者包含许多指向相关资源的链接时,它会变得更加复杂。

以博客文章为例,考虑一个返回博客文章快照的资源 - 包括此博客文章的作者,标签和评论。 显然,这个资源包含许多子资源,当然也应该提供单独的链接:

Sample Resource:

{
   "blogpost":{
      "link":{
         "rel":"self",
         "href":"http://blog/post/4711"
      },
      "author":{
         "name":"Bob",
         "link":{
            "rel":"???",
            "href":"http://author/uri"
         }
      },
      "title":"foobar",
      "content":"A long article here…",
      "comments":[
         {
            "comment":"great article",
            "link":{
               "rel":"???",
               "href":"http://blog/post/4711/comment/1"
            },
            "author":{
               "name":"John Doe",
               "link":{
                  "rel":"???",
                  "href":"http://author/uri"
               }
            }
         }
      ],
      "tags":[
         {
            "value":"foo",
            "link":{
               "rel":"???",
               "href":"http://blog/post/4711/tag/foo"
            }
         }
      ]
   }
}

那么给定链接的适当关系是什么?我知道存在tag等关系类型,但并非所有资源都与现有关系类型相匹配。或者在引用author / tag / comment时是否可以使用self,因为它与封闭的JSON(子)对象的上下文有关?什么是语义实体self指的是什么?

RFC 5988声明:

  

链接的上下文是Feed IRI或条目ID,具体取决于它出现的位置

如何根据JSON解释这一点?每个新对象{…}都是新的上下文吗?

谢谢!

3 个答案:

答案 0 :(得分:13)

这是一个很好的问题。如果查看Hal的示例,您将看到rels是在子资源的上下文中定义的。
关于何时rel与整个资源或包含的子资源相关,我不知道任何明确的指南 我可以指出的唯一额外信息是RFC5988中的锚参数,它允许您使用片段或全新的URI重新定义上下文IRI。

理想情况下,您的mediatype应说明嵌套资源的上下文IRI是否不同,或者是否需要显式更改上下文IRI。这将是使用像application / vnd.hal + json这样的媒体类型而不是普通的旧应用程序/ json的另一个优点,正如Hal规范所述:

  

@rel - 用于识别目标URI与“主题”的关系   资源”。主题资源是最接近的父资源   元件。

答案 1 :(得分:8)

LSON-LD

您可以查看JSON-LDLinked Data的JavaScript对象表示法。它看起来比HAL更复杂,但您可以使用它做更多的事情。

JSON-LD正在W3C内部进行标准化,here is the proposal recommendation

另外

抱歉,我没有时间提供示例..

答案 2 :(得分:-7)

回答这个问题有点晚,但为了将来参考,这就是我解决这个问题的方法:

{
   "blogpost":{
      "title":"foobar",
      "content":"A long article here…",
      "link":{
         "rel":"self",
         "href":"http://blog/post/4711"
      },
      "link":{
         "rel": "author",
         "href": "http://author/uri",
         "alt":"Bob"
      },
      "link":{
        "rel": "comment",
        "alt": "great article",
        "href":"http://blog/post/4711/comment/1"
      },
      "link": {
        "rel":"tag",
        "href":"http://blog/post/4711/tag/foo",
        "alt":"foo"
      }
   }
}

当你考虑它时,评论,标签等都是与你的帖子相关的不同资源......为什么不把它们全部都变成它们的链接!您甚至可以节省回复的大小;)