我正在为我公司的内部数据设计一个HATEOAS API,但是在发现链接方面遇到了麻烦。请考虑以下一组步骤,以便某人检索有关此系统中特定员工的信息:
http://coredata/
发送GET以获取所有可用资源,返回一些链接,包括一个标记为rel =“http://coredata/rels/employees
”的链接http://coredata/employees
从最后一次通话中返回的数据是我的难题,也是我听到过混合建议的情况。以下是其中一些:
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" } }
我有点被困在最接近HATEOAS的地方。对于选项1,我真的不想让我的客户每次都为了导航而检索所有员工,但我可以看到在示例二中使用URI模板如何引入一些带外知识
我的另一个想法是使用RetrieveOne,Query和All操作作为我的酷网址,但这似乎违反了您应该能够从一个基本URI导航到所需资源的概念。
有没有其他人设法找到一个好方法来处理这个问题?一旦您检索到一个资源或一组资源,导航就变得简单了,但似乎很难用于发现。
答案 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" }
...
}}