簡體   English   中英

REST API 設計 - 適配器服務 - 如何標記不同方向的端點?

[英]REST API Design - adapter service - how to mark endpoints for different directions?

讓我們想象一個 web 服務X有一個單一的目的 - 幫助集成具有不同域模型的兩個現有服務( AB )。 某種適配器模式。

有A想打電話給B的情況,也有B想打電話給A的情況。

應該如何命名 X 的端點以明確每個端點所指的方向?

例如,假設服務 A 管理“蘋果”。 並且服務 B 想要獲取有關“蘋果”的更新。

適配器服務 X 將有兩個端點:

  • PUT /apples - 當A想要將更新的“蘋果”推送到B
  • GET /apples - 當B想從A讀取“蘋果”時(不等待A的推送)

在此處輸入圖像描述

上述端點結構非常具有誤導性。 端點完全不同,使用不同的域模型:PUT-endpoint 等待 A 的 model,GET-endpoint 返回 B 的 model。

在這種情況下,我將不勝感激有關設計 API 的任何建議。

我不喜歡我自己的變體:

PUT /gateway-for-A/apples
GET /gateway-for-B/apples

不知道為什么需要在路徑中區分它以及為什么域或子域不足以滿足它:

A: PUT x.example.com/apples -> X: PUT b.example.com/apples
B: GET x.example.com/apples -> X: GET a.example.com/apples

從 model 開始,您希望在為 REQ-REP 設計的系統中執行 PUSH-PULL。 讓我們翻譯上面的內容: pushApples(apples)pullApples() -> apples如果這就是他們所做的一切,那么PUTGET就可以使用/apples URI,如果你問我的話。 如果您只需要更新,也許/apples/new更具表現力,但我寧願使用if-modified-since header 代替,也可以使用if-unmodified-since推送。

盡管我認為您應該描述這兩個服務的作用,而不是您對蘋果的作用,它們似乎是數據庫實體的集合,而不是 web 資源,后者位於數據庫之上幾層。 目前,您的 URI 描述的是通信,而不是服務。 例如為什么 X 是必要的,為什么他們不直接互相調用? 如果你能回答這個問題,那么你就會明白 X 對蘋果做了什么,如何命名它的操作以及如何設計描述它們的 URI 和方法。

首先要做的事情: REST 沒有端點,但有資源

接下來,就 HTTP 而言,您應該使用相同的 URI 來更新資源的 state 並檢索對其進行的更新作為緩存,它基本上使用資源的有效 URI,如果非-對其執行安全操作並將請求轉發到實際服務器。 如果您將關注點拆分到不同的 URI 上,您基本上完全繞過了在后台為您執行的緩存管理。

進一步注意,HTTP/0.9、HTTP/1.0 和 HTTP/1.1 本身沒有“推送”選項。 它是一個請求-響應協議,因此如果客戶端有興趣對資源進行更新,它應該在需要更新時輪詢相應的資源。 如果您需要上述推送,但您基本上需要切換到 Web Sockets 等。 雖然 HTTP/2 引入了服務器推送功能,但這實際上只是填充了 本地二級緩存,防止客戶端有效地請求資源,而是使用先前接收和緩存的資源。

上述端點結構非常具有誤導性。 端點完全不同並且使用不同的域模型:PUT-endpoint 等待 A 的 model,GET-endpoint 返回 B 的 model。

資源不應該 map 您的域 model 1:1。 通常在 REST 架構中,資源可能比域 model 中的實體多得多。 只需考慮向客戶端解釋如何請求創建或更新資源等的類似表單的資源。

在 Web 以及 REST 架構中,交換的表示格式應基於明確定義的媒體類型。 這些媒體類型應該定義可以在此類交換文檔中找到的元素的語法和語義。 特別是元素提供了一種啟示,特別是告訴客戶某些元素可以用於什么。 即想要按下按鈕,同時可以向左或向右拖動 slider 以更改一些數值等。 一旦將對該媒體類型的支持添加到您的客戶端和/或服務器,您就不必頻繁訪問任何外部文檔。 A rule of thumb in regards to REST is to design the system as if you'd interact with a traditional Web page and then apply the same concepts you used for interacting with that Web page and translate it onto the REST application domain.

客戶端和服務器還應該使用內容類型協商來協商服務器應該為響應生成哪種表示格式,以便客戶端可以處理它們。 REST 是關於最終允許服務器更改其內部而不影響行為良好的客戶端的間接性。 在更改的同時保持互操作性是 REST 的固有設計決策。 如果這對您來說不重要,那么 REST 可能對您的需求來說太過分了,您可能應該使用更多基於(Web-)RPC 的東西。

關於您的實際問題,IMO 消息隊列可能比試圖將您的設計強制到 REST 架構上更適合您的問題。

在我看來,這很好,但可以改進:

PUT /gateway-for-A/apples
GET /gateway-for-B/apples

因為

可以改進的地方:

  • 最好使用小寫
  • 刪除不必要的詞

所以我會堅持使用以下 URI:

PUT /a/apples
GET /b/apples

在此處閱讀有關Restful API 命名約定的更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM