簡體   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