1

我理解 HATEOAS 通过发送所有可以在应用程序内执行的操作作为响应(HAL、JSON-LD 等)来表示应用程序状态。

例如,查看银行的账户资源可能允许您存款、取款或关闭账户(可能返回 UPDATE 和 DELETE 动词的选项)。

就这些链接的运行时可发现性(由消费客户端)而言,如何处理呢?

如果发送这些链接的目的是将客户端与服务器解耦并通过响应中的超媒体驱动状态,则开发人员必须在应用程序中硬编码一定数量的知识才能理解响应的含义回来。

我理解发送 OPTIONS 请求是确定资源当前状态以及下一步可以做什么的方法,但是为了发现要使用的实际 URI - 这些是否会简单地硬编码为 COOL URI?

4

2 回答 2

2

就像@VoicesOfUnreason 所说,在 HATEOAS 中,URI 是可发现的(并且没有记录在案),因此可以更改它们。也就是说,除非它们是您系统的入口点(Cool URIs,唯一可以由客户端硬编码的入口点) - 如果您希望能够发展其余部分,那么您不应该拥有太多的入口点未来系统的 URI 结构。这实际上是REST最有用的特性之一。

对于剩余的非酷 URI,它们可以随着时间的推移而更改,并且您的 API 文档应该说明它们应该在运行时通过超媒体遍历发现的事实。

查看Richardson 的成熟度模型(第 3 级),这将是链接发挥作用的地方。例如,从顶层,比如 /api/version(/1),您会发现有一个指向组的链接。这是在HAL Browser之类的工具中的外观:

根:

{
  "_links": {
    "self": {
      "href": "/api/root"
    },
    "api:group-add": {
      "href": "http://apiname:port/api/group"
    },
    "api:group-search": {
      "href": "http://apiname:port/api/group?pageNumber={pageNumber}&pageSize={pageSize}&sort={sort}"
    },
    "api:group-by-id": {
      "href": "http://apiname:port/api/group/id" (OR "href": "http://apiname:port/api/group?id={id}")
    }
  }
}

添加只是到该端点的 POST,然后您将拥有 2 个 GET 方法。

GET /api/group?pageNumber=0&pageSize=20&sort=asc

这可能会返回如下内容:

{
    "groups": [
      {
        "id": 123,
        "name": "Test Group"
      }, 
      {
        "id": 134,
        "name": "Tennis squad"
      }
    ]
}

然后,一旦您深入到特定组(例如#123):

{
  "Id" : 123,
  "Name" : "test",
  "_links": {
    "self": {
      "href": "/api/group/1" (OR "/api/group?id=1")
    },
    "edit": {
      "href": "http://apiname:port/api/group/1"
    },
    "api:delete": {
      "href": "http://apiname:port/api/group/1"
    },
    "api:items-query": {
      "href": "http://apiname:port/api/bonus?groupId=1"
    }
  }
}

在这里,编辑只是一个 PUT,然后您需要一个 DELETE(请参阅同一链接中的 REST 级别 2),至于项目,您可能最清楚它们只是一个属性还是另一个端点;您甚至可以将它们嵌入到检索组的同一个调用中。

这里的优点是客户端只需要知道关系(链接)名称(显然除了资源结构/属性之外),而服务器几乎可以自由地更改关系(和资源)url。

于 2016-09-13T07:06:14.843 回答
0

有很多关于尝试创建富有表现力的、可发现的超媒体的现有技术。您可能想要查看:

我在想可能是一系列 if 语句检查某些属性以确定状态,甚至可能是 switch 语句。这是正确的路径 - 还是有更好的超媒体发现方法?

我目前的想法是,您希望更多地按照谈判和遵循协议来塑造自己的想法;所以想想状态机而不是 if 语句。

对于初学者,请查看如何获得一杯咖啡

RESTBucks 提供的文档中的超链接旨在帮助客户端协商 RESTBucks 协议;客户已经理解协议的假设被纳入模型。换句话说,客户已经明白协商协议将允许它达到它的目标

当然,可能有多种协议服务于同一目标。例如,RESTBucks 还可以支持“Give Away Day Old Coffee”协议;宣布每个人的存在,客户将被期望选择哪个是目标的更好表达,并遵循该路径。

于 2016-09-12T17:24:25.247 回答