如何正确使用HAL(超媒体应用程序语言)_embedded?

时间:2015-06-04 14:45:09

标签: api rest hateoas

我正在构建一个REST API,向用户公开有关在线课程的信息。以下是课程的一般结构:

课程>单位>课程>活动

我试图让我的JSON响应结构符合HAL标准,但我不确定我是否正确地执行了此操作。

以下哪项是正确的:

{
      “kind”: “clms#course”,
      “id”: long,
      “course-name”: string,
      “course-icon”: string,
      “product-name”: string,
      “product-icon”: string,
      “_links”: {
        “self”: {“href” : string}, 
      }
      "_embedded": {
        “unitlist”: {“href” : string} // This is a link to list of units for the course.
      }
    }

或者是_embedded资源单元列表的链接?

if-else

或者都错了!?任何帮助表示赞赏。

干杯, 奥利

1 个答案:

答案 0 :(得分:1)

很少有事情。让我带你完成整个过程,它可能有所帮助。

从链接及其关系开始。有一个课程,它有单位。因此每个单元都与课程相关。用它作为你的关系名称。这样:

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    “unit”: [
       {“href” : url-of-first-unit},
       {“href” : url-of-second-unit},
       {“href” : url-of-third-unit},
       ...
    ]
  }
}

但是单位不是IANA注册的链接关系,因此它实际上应该是一个URI,或者是一个URI:

“_links”: {
    “self”: {“href” : string},
    "curies" : [
       {"href" : "http://youndomain/rels/{rel}", name : "x" }
    ],
    “x:unit”: [
       {“href” : url-of-first-unit},
       {“href” : url-of-second-unit},
       {“href” : url-of-third-unit},
       ...
    ]
  }

这有点令人困惑,但它使得你的单位是“命名空间”并且它本身就是好的。

现在意识到单独检索所有这些单位会很痛苦。我假设你的UI中你想要显示单元和课程,所以HAL让你嵌入这些关系:

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    "curies" : [
       {"href" : "http://youndomain/rels/{rel}", name : "x" }
    ],
    “x:unit”: [
       {“href” : url-of-first-unit},
       {“href” : url-of-second-unit},
       {“href” : url-of-third-unit},
       ...
    ]
  },
  "_embedded" : {
    “x:unit”: [
       { some json representing the unit located at url-of-first-unit},
       { some json representing the unit located at url-of-second-unit},
       { some json representing the unit located at url-of-third-unit},
       ...
    ]
  }
}

现在客户可以让我的单位检查嵌入而不是检查链接。事实上,因为它是嵌入式的,所以没有理由再包含链接(除非你知道客户端依赖于它们):

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    "curies" : [
       {"href" : "http://youndomain/rels/{rel}", name : "x" }
    ],
  },
  "_embedded" : {
    “x:unit”: [
       { some json representing the unit located at url-of-first-unit},
       { some json representing the unit located at url-of-second-unit},
       { some json representing the unit located at url-of-third-unit},
       ...
    ]
  }
}

所以现在客户端将它们作为嵌入式资源提供,并且不需要使用http请求检索资源。

总的来说,我建议从所有内容的链接开始,并通过嵌入式资源优化您的用例。

几个额外的笔记:

  • 如果你真的需要一起收集所有单位 单个资源,也许可以将其视为具有嵌入式的页面 item [s]将是单位。从课程到关系的关系 单位[s]的页面可能是x:单位。
  • 避免在您的资源上使用id字段,除非id是外部已知的内容。自我链接是一个更好的外部ID,因为它是一个 URL并且更容易变成实际资源。
  • 我更喜欢配置文件链接而不是“kind”字段,尤其是当它看起来像枚举时。看看https://tools.ietf.org/html/rfc6906