REST / HATEOAS-HAL链接中的可用方法

Jos*_*mez 8 api rest json hateoas

我正在考虑使用HATEOAS定义REST API 。特别是,我发现非常有趣的概念,即为给定资源指示当前可用的操作。

某些HATEOAS规范包含太多无法满足我需要的开销,因此我查看了HAL规范,因为我发现它非常简洁实用:

{
    _links: {
        self: { href: "/orders/523" },
        warehouse: { href: "/warehouse/56" },
        invoice: { href: "/invoices/873" }
    },
    currency: "USD",
    status: "shipped",
    total: 10.20
 }
Run Code Online (Sandbox Code Playgroud)

但是,HAL中的链接仅包含相关资源的列表,但不包含对它们的可用操作。按照上面的示例,我现在是否可以取消订单,还是不能取消?一些HAL示例通过使用特定的URL进行取消来解决此问题,并仅在可能取消的情况下在响应中添加相应的链接:

"cancel": { "href": "/orders/523/cancel" }
Run Code Online (Sandbox Code Playgroud)

但这不是非常RESTful的。取消不是资源。取消是对资源的删除,即:

DELETE /orders/523
Run Code Online (Sandbox Code Playgroud)

有没有一种很好的方法可以用HAL表示这一点,还是应该使用其他HATEOAS规范?

我正在考虑返回带有与self相同的URL的“取消”链接,但是在这种情况下,客户端必须知道要取消操作,他们必须使用DELETE动词,而HATEOAS响应中并未对此进行详细描述。

self: { "href": "/orders/523" },
cancel: { "href": "/orders/523" }
Run Code Online (Sandbox Code Playgroud)

这是HATEOAS / HAL的推荐方法吗?我了解HAL没有任何“方法”参数,而我自己添加该参数将违反HAL规范。

Voi*_*son 5

一些HAL示例通过使用特定的URL进行取消来解决此问题,并且仅在可能取消的情况下在响应中添加相应的链接

是。就像网站一样:如果您想提醒客户端可能到达其他应用程序状态,则可以为客户端提供一个链接,其中包括所涉及资源的标识符。

但这不是非常RESTful的。

它可能不是“ RESTful”的,但肯定符合REST体系结构样式

取消是对资源的删除,即:DELETE / orders / 523

您正在将域模型上的操作与集成模型上的操作混淆。REST API的作用是通过协议指导客户端以达到某种目的。它不是语义到HTTP 的映射。

Jim Webber这样说:

网络不是您的域名;这是一个文档管理系统。所有HTTP动词都适用于文档管理域。URI不会映射到域对象上-这违反了封装。工作(例如:向域模型发布命令)是管理资源的副作用

REST约束之一是统一接口;对于HTTP,这意味着所有资源都以统一的方式理解方法;DELETE 表示RFC 7231第4.3.5节中描述的语义。

换句话说,如果我发送请求

OPTIONS /x/y/z/foobar ...
Run Code Online (Sandbox Code Playgroud)

并且响应在Allow标头中包含DELETE ,那么我知道这意味着什么。您网域的副作用?我对副作用一无所知。

在DELETE的定义中,请注意以下几点

相对而言,很少有资源允许使用DELETE方法-它的主要用途是用于远程创作环境,在该环境中,用户可以对其效果有所了解。

无论如何,您并不是真正在问DELETE,而是关于HAL

有没有一种很好的方法可以用HAL表示这一点,还是应该使用其他HATEOAS规范?

据我所知,执行此操作的官方方法是使用链接关系对其进行记录。换句话说,不是使用“取消”作为链接关系,而是使用类似

https://tools.ietf.org/html/rfc5023#section-5.4.2

然后,如果您的消费者想要发现链接的用途,则可以按照关系来了解发生了什么。

HAL讨论:为什么没有方法? 有很多好的信息。

我喜欢Mike Kelly的摘要:

这个想法是可用的方法可以通过链接关系文档来传达,而不必在json消息中。