HATEOAS - 发现和URI模板

时间:2012-10-26 17:03:54

标签: rest discovery hateoas

我正在为我公司的内部数据设计一个HATEOAS API,但是在发现链接方面遇到了麻烦。请考虑以下一组步骤,以便某人检索有关此系统中特定员工的信息:

  1. 用户向http://coredata/发送GET以获取所有可用资源,返回一些链接,包括一个标记为rel =“http://coredata/rels/employees”的链接
  2. 用户在第一个请求的rel上关注HREF,执行GET(例如)http://coredata/employees
  3. 从最后一次通话中返回的数据是我的难题,也是我听到过混合建议的情况。以下是其中一些:

    1. GET将返回所有员工(可能会截断数据),客户端将负责从该列表中选择所需的人员。
    2. GET会返回一些URI模板化链接,描述如何查询/获取一名员工/获取所有员工。类似的东西:

      "_links": {
          "http://coredata/rels/employees#RetrieveOne": {
              "href": "http://coredata/employees/{id}"
          },
          "http://coredata/rels/employees#Query": {
              "href": "http://coredata/employees{?login,firstName,lastName}"
          },
          "http://coredata/rels/employees#All": {
              "href": "http://coredata/employees/all"
          }
      }
      
    3. 我有点被困在最接近HATEOAS的地方。对于选项1,我真的不想让我的客户每次都为了导航而检索所有员工,但我可以看到在示例二中使用URI模板如何引入一些带外知识

      我的另一个想法是使用RetrieveOne,Query和All操作作为我的酷网址,但这似乎违反了您应该能够从一个基本URI导航到所需资源的概念。

      有没有其他人设法找到一个好方法来处理这个问题?一旦您检索到一个资源或一组资源,导航就变得简单了,但似乎很难用于发现。

3 个答案:

答案 0 :(得分:3)

选项2并不太糟糕,因为您使用RFC 6570来表征URI模式;虽然HATEOAS通常以没有客户端合成URI的方式声明,但如果服务器准备在URI模板上做出保证并以标准格式明确告诉客户端,那么它是可以接受的。 (我很想让“list all employees”URL没有all后缀,以便将其与具有该ID的员工区分开;客户端原则上不应该知道员工ID的外观等。)

实际上,主要问题实际上是客户必须了解那些标签URI的含义;没有真正的方法可以猜测“http://coredata/rels/employees#All”意味着“列出所有员工”。这就是你在客户,语义标签等方面嵌入知识的地方,而HATEOAS并没有真正解决这些问题。

答案 1 :(得分:1)

TL; DR:使用OPTIONS方法以编程方式返回耗材文档并始终实施分页。

我们在工作中创建了许多内部REST服务。我们已经使用OPTIONS方法标准化来返回资源的元数据。我们返回的元数据是该资源的可分析文档。它表示URL模板,各种选项,如PAGE,PAGESIZE和资源支持的不同方法。我们还返回rel链接,因此可以使用OPTIONS进行顶级资源发现,而无需提取和实际数据。

我们还专门实施分页,以防止不必要地返回大量数据的问题。

答案 2 :(得分:0)

我的HATEOAS API返回HTML以及HAL+JSON,正如您所使用的那样,它们都使用相同的URI,因此我的JSON响应只返回人类Web用户将看到的内容(减去所有漂亮的颜色) 。 e.g。

GET /


{"_links": {
    "http://coredata/companies": { "href": "/companies?page=1" }
    ...
}}



GET /companies?page=1


{"_links": {
    "next": { "href": "?page=2" }
    ...
}}