我正在使用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/

10-09 20:24