繁体   English   中英

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

[英]REST/HATEOAS - Available methods in HAL links

我正在寻找使用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
 }

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

"cancel": { "href": "/orders/523/cancel" }

但那不是非常RESTful。 取消不是资源。 取消是资源的DELETE,即:

DELETE /orders/523

有没有一种很好的方式用HAL表示这个,或者我应该使用不同的HATEOAS规范?

我正在考虑使用与self相同的URL返回“取消”链接,但在这种情况下,客户端必须知道要取消它们必须使用DELETE动词,这在HATEOAS响应中并未真正描述。

self: { "href": "/orders/523" },
cancel: { "href": "/orders/523" }

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

一些HAL示例通过使用特定URL进行取消来解决此问题,并且只有在可以取消时才在响应中添加相应的链接

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

但那不是非常RESTful。

它可能不是“RESTful”,但它肯定符合REST架构风格

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

您将域模型上的操作与集成模型上的操作混淆。 REST API的作用是引导客户端通过协议来实现某些目的; 不是 语义到HTTP的映射。

吉姆韦伯这样说:

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

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

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

OPTIONS /x/y/z/foobar ...

并且响应包括Allow头中的 DELETE,然后我就知道它意味着什么。 您域中的副作用? 我对副作用一无所知。

在DELETE的定义中,请注意以下内容

相对较少的资源允许使用DELETE方法 - 它主要用于远程创作环境,其中用户对其效果有一些指导。

无论如何,你并不是真的在询问DELETE,而是关于HAL

有没有一种很好的方式用HAL表示这个,或者我应该使用不同的HATEOAS规范?

据我所知,正式的做法是用链接关系来记录它。 换句话说,不是使用“取消”作为链接关系,而是使用类似的东西

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

然后您的消费者,如果他们想要发现链接的用途,可以按照关系来了解正在发生的事情。

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

我喜欢Mike Kelly的总结:

我们的想法是可以通过链接关系文档传达可用的方法,而不需要在json消息中。

根据LosTechies的这篇文章,从CQRS的角度来看,它接受使用以下URL: /orders/<id>/<command>并使用PUT请求调用它们。 所以可以使用"cancel": { "href": "/orders/523/cancel" }

但是,如果你绝对想要使用DELETE而你只使用命令链接来修改你的资源(即/orders/<id>/<command> ),那么为什么你不能只添加一个链接,例如"cancel": { "href": "/orders/523" }并扣除HTTP动词? 我的意思是根据REST,只有5个主要动词(GET,POST,PUT,PATCH和DELETE)。 我们不能在诸如/<ressource>/<id>类的URL上使用POST,GET已经被定义为“自我”关系,我们在上面提到修改(PUT)将由命令链接处理(即/<ressource>/<id>/<command> )因为我们使用命令链接,所以不需要使用PATCH。 之后,剩下的唯一选择是:DELETE。

它并不完美,但它有效并且不会违反任何惯例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM