就像@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。