2009-02-02 143 views
3

我有一個公開的方法將字段添加到一個WebService

TradeDetail getTradeDetail() 

TradeDetail店5場,交易數量,日期等對SOAP服務

我需要幾個字段添加到TradeDetail。我想保持(一會兒)的向後兼容性,它看起來好像我的選擇是有限的,以創建一個新的類的額外字段

TradeDetail2 getTradeDetail2() 

現在,這將工作 - 我以前做過。但是有沒有人們使用過的其他解決方案?

E.g.

  • 從根本上改變TradeDetail2添加名稱值對。
  • 繼承TradeDetail TradeDetail2,這將減少代碼,但會增加耦合
  • 返回XML或JSON代替

我就能很快退休的原接口,這樣的代碼將得到清理和額外的TradeDetail2不會永遠持續!

感謝

回答

3

我同情 - 我的一些Web服務都與myMethod()myMethod2()myMethod3()等僅僅是因爲我需要添加一些新的領域千瘡百孔。

對於您來說,保留方法名稱併爲每個API版本創建一個新端點會有意義嗎?例如:

然後你的方法名留懂事,不管有多少未來的變化,你需要做。

任何使用您的webservice的應用程序都可能需要重新編寫和/或針對新的WSDL進行重新編譯,以利用新的字段,爲什麼不只是讓它們針對新的v1.1 API進行重寫/重建。

我發現這也有助於與使用您的服務的應用程序的所有者/開發人員進行溝通 - 例如,「[日期]之後,我們的Web服務API版本[舊]將不再受支持,請確保您正在使用至少版本[新]

3

這就是爲什麼我更喜歡完全控制XML到對象的映射,所以我可以從XML接口分離模型。在你的情況下,我只需將新字段添加到TradeDetail,並考慮它們是「可選」以實現向後兼容性。這將是例如XML->在框架我的團隊使用,爲您的界面書面TradeDetail對象映射:

// this would go into my client endpoint class 
public TradeDetail getTradeDetail() { 
    Element requestRoot = new Element("GetTradeDetail"); 
    Element responseRoot = invokeWebServiceAndReturnJdomElement(requestRoot); 
    return mapTradeDetail(responseRoot); 
} 

// this would go into my client XO mapping class 
public TradeDetail mapTradeDetail(Element root) { 
    TradeDetail tradeDetail = new TradeDetail(); 
    tradeDetail.setField1 = fetchString(root, "/GetTradeDetail/Field1"); 
    tradeDetail.setField2 = fetchInteger(root, "/GetTradeDetail/Field2"); 
    tradeDetail.setField3 = mapField3(root, "/GetTradeDetail/Field3"); 
    tradeDetail.setField4 = fetchString(root, "/GetTradeDetail/Field4"); 
} 

這類型的客戶會忽略新的領域,因而是有協議的新版本兼容,直到我添加這樣的事情同樣的方法結束在第2版:

if (fetchXPath(root, "/GetTradeDetail/Field5") != null) { 
    // so we're talking with server which speaks new version of protocol 
    tradeDetail.setField5 = fetchString(root, "/GetTradeDetail/Field5"); 
} 

服務器將與類似的代碼的工作,可能是檢查客戶端版本,並映射只有當客戶端支持協議的新版本額外的字段。

在我看來,應該編寫客戶端,以便添加到協議中的少量額外字段不會中斷客戶端 - 我沒有奢望因爲上游提供商添加新功能而沒有通知我關於它。如果提供商更改現有的必填字段,當然客戶需要修改。這就是爲什麼上游提供商應該版本協議並支持舊版本至少幾個月。