[英]How to add additional attributes to links using Spring Hateoas and 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规范?
据我所知,正式的做法是用链接关系来记录它。 换句话说,不是使用“取消”作为链接关系,而是使用类似的东西
然后您的消费者,如果他们想要发现链接的用途,可以按照关系来了解正在发生的事情。
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.