我正在使用HATEOAS定义REST API。特别是,对于给定资源指示当前可用的操作的概念,我发现非常有趣。
某些HATEOAS规范包含过多的开销以满足我的需求,因此我查看了HAL specification,因为它非常简洁实用:
{
_links: {
self: { href: "/orders/523" },
warehouse: { href: "/warehouse/56" },
invoice: { href: "/invoices/873" }
},
currency: "USD",
status: "shipped",
total: 10.20
}
但是,HAL中的链接仅包含相关资源的列表,但不包含对它们的可用操作。按照上面的示例,我是否可以立即取消订单,还是不能取消订单?一些HAL示例通过使用特定的URL进行取消来解决此问题,并且仅在可能取消的情况下在响应中添加相应的链接:
"cancel": { "href": "/orders/523/cancel" }
但这不是非常RESTful的。取消不是资源。取消是对资源的删除,即:
DELETE /orders/523
有没有一种很好的方法可以用HAL表示这一点,还是应该使用其他HATEOAS规范?
我正在考虑返回一个具有与self相同的URL的“取消”链接,但是在这种情况下,客户端必须知道要取消操作,他们必须使用DELETE动词,而HATEOAS响应中并未对此进行详细描述。
self: { "href": "/orders/523" },
cancel: { "href": "/orders/523" }
这是HATEOAS/HAL的推荐方法吗?我了解HAL没有任何“方法”参数,而我自己添加该参数将违反HAL规范。
最佳答案
是的。就像网站一样:如果您想提醒客户端可能会达到其他应用程序状态,则可以为客户端提供一个链接,其中包括所涉及资源的标识符。
它可能不是“RESTful”的,但肯定符合REST architectural style。
您正在将域模型上的操作与集成模型上的操作混淆。 REST API的作用是通过协议(protocol)指导客户端以达到某种目的。它不是域语义到HTTP的映射。
吉姆·韦伯(Jim Webber)这样说:
REST约束之一是uniform interface;在HTTP的情况下,这意味着所有资源都以统一的方式理解方法; DELETE表示RFC 7231, section 4.3.5中描述的语义。
换句话说,如果我发送请求
OPTIONS /x/y/z/foobar ...
并且响应在Allow header中包含DELETE,那么我知道这意味着什么。您网域中的副作用?我对副作用一无所知。
在DELETE的定义中,请注意以下几点
无论如何,您并不是真正在问DELETE,而是关于HAL
据我所知,执行此操作的官方方法是使用链接关系对其进行记录。换句话说,不是使用“取消”作为链接关系,而是使用类似
然后,如果您的消费者想要发现链接的用途,则可以按照这种关系来了解发生了什么。
HAL Discuss: Why No Methods?有很多好的信息。
我喜欢Mike Kelly的摘要:
关于json - REST/HATEOAS-HAL链接中的可用方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44944728/