2016-03-25 37 views
6

已推薦版本終點時青睞defensively evolving a DTO over time,但我發現很難不失什麼,我認爲通過ServiceStack提供一些關鍵的有益的功能做。在對我的API進行版本控制時,如果我使用相同的DTO,如何維護Swagger文檔?

我目前使用的ServiceStack V3,但是可以升級到V4,如果/當需要時。

在實現我的服務,我可以指定get()方法與不同的合同的多個實現,並且ServiceStack映射數據進來相應。

作品:

public object Get(EntityBrowse) { ... } // returns multiple of a single entity 
public object Get(Entity) { ... } // returns a single entity 

也可以工作:

public object Get(Contracts.v1.Entity) { ... } 
public object Get(Contracts.v2.Entity) { ... } 

不起作用:

public object Post(Contracts.v1.Entity) { ... } 
public object Post(Contracts.v2.Entity) { ... } 

此情況下不能正常工作的地步,通過這個來的所有帖子服務映射到v1合同,即使這些字段不匹配。即使是那些笨拙的文檔也顯示了錯誤的v1屬性,但是v2 DTO中的正確的摘要/註釋。

我想有一個單獨的DTO對於給定端點的每一個主要版本有幾個原因:

  1. 揚鞭。從包含很多字段的DTO生成的Swagger文檔可能會讓公共API的最終用戶感到困惑。用戶如何知道哪些字段適用於他們想要使用的端點版本?我可以將每個字段記錄下來,但我認爲向最終用戶顯示他們當時所關心的字段比較容易。不同的客戶會在不知道v1存在的情況下使用v2。

  2. 驗證。 ServiceStack爲每個類型提供驗證器。這是完美的,除了如果我的DTO的必需字段可能會隨着時間漂移,我不能繼續使用同一個驗證器沒有一些特殊的外殼。也許這是一個可以接受的損失?

  3. 棄用。一段時間後,v1將被棄用。 V1代表端點的遺產執行,之前有版本,和之前有實體之間是一致的合同(例如,使用「名」與「標題」,「TYPEID」與「類型」)。在這個看起來更合理之後,隨着時間的推移發展一個DTO,但是當v1存在時,終端受到開發者在十年前做出的決定的限制。

在閱讀了幾遍後,我想我應該創建單獨的服務來支持舊功能。

我的端點版本之間的主要區別是:

  • 權限
  • 字段名
  • 組織和領域的映射(例如,去除嵌套對象)
  • 實現細節(例如,默認返回多少結果)

我應該考慮打破我的版本分開服務?我是否應該加載一個包含所有字段的單個DTO,並概述每個屬性支持的版本?

回答

3

我強烈建議不要在同一個服務中使用同一個請求DTO的多個版本,您應該改爲version your DTO's defensively,以便您的請求DTO可以支持多個版本。這是特別糟糕的嘗試保持靜態類型的語言,導致大量摩擦,重複代碼,維護等相同服務的多個版本。

如果您必須維護不同的版本,我建議維護和託管不同的版本分支機構,並有一個反向代理將/v1//v2/ API請求重定向到舊的和新的ServiceStack實例。這樣一旦所有客戶都遷移到v1之後,您就可以放棄它,並且您的v2將會保持清潔,而無需傳統的v1版本感染當前的代碼庫。但我的建議是在防禦上對相同的Request DTO進行版本化,所以您不必維護多個版本,ServiceStack的基於消息的設計使得這更容易。它還會減少內部和外部的混淆,試圖維護多個版本對於維護服務的開發人員和任何使用它們的人員來說都是令人困惑的。

在ServiceStack中,每個請求DTO類型應該是唯一的並且只有一個實現,但是大多數元數據服務要求請求DTO名稱也是唯一的,並且Add ServiceStack Reference中的許多語言也要求所有DTO都是唯一的,我們的建議。如果您絕對必須擁有不同版本的不同類型,請在請求DTO上附加版本,例如GetEntitiesV1GetEntitiesV2 - 這些名稱將使用您發佈的自定義路由向用戶隱藏。

ServiceStack's Swagger Support在v4中看到了很多更新,如果您在v3中發現問題,則可以使用Free Quotas in v4來查看問題是否已解決。

相關問題