一、分包分發
建議将服務接口、服務模型、服務異常等均放在 API 包中,因為服務模型和異常也是 API 的一部分,這樣做也符合分包原則:重用釋出等價原則(REP),共同重用原則(CRP)。
異常聲明處理是服務調用中不可缺少的部分。通常服務提供方定義明細業務錯誤異常碼,調用方進行捕獲處理。進一步的異正常約我們稍後會具體說明。
二、接口粒度
接口粒度:服務接口盡可能大粒度,每個服務方法應代表一個功能,而不是某功能的一個步驟,否則将面臨分布式事務問題。也就是說同一個操作功能場景盡可能囊括到一個服務裡,減少調用關聯方。
抽象:服務接口建議以業務場景為機關劃分,并對相近業務做抽象,防止接口數量爆炸。不建議使用過于抽象的通用接口,如:
Map query(Map)
,這樣的接口沒有明确語義,會給後期維護帶來不便。
三、服務版本
如果可能,有必要細粒度版本化到服務接口級别,以更好的控制服務疊代更新。
建議使用兩位版本号,因為第三位版本号通常表示相容更新,隻有不相容時才需要變更服務版本。
當不相容時,先更新一半提供者為新版本,再将消費者全部升為新版本,然後将剩下的一半提供者升為新版本。
四、更新相容性
除非是新的功能服務接口,舊的服務更新必須處理接口的向後相容性。
接口增加參數或者傳回值增加字段一般可以相容,涉及修改或者删除則及枚舉類型使用時,則需要通過版本号更新處理。
枚舉值:
如果是完備集,可以用
Enum
,比如:
ENABLE
,
DISABLE
。
如果是業務種類,以後明顯會有類型增加,不建議用
Enum
,可以用
String
代替。
如果是在傳回值中用了
Enum
,并新增了
Enum
值,建議先更新服務消費方,這樣服務提供方不會傳回新值。
如果是在傳入參數中用了
Enum
,并新增了
Enum
值,建議先更新服務提供方,這樣服務消費方不會傳入新值。
五、序列化
服務參數及傳回值建議使用 POJO 對象,即通過
setter
,
getter
方法表示屬性的對象。
服務參數及傳回值都必須是傳值調用,而不能是傳引用調用,消費方和提供方的參數或傳回值引用并不是同一個,隻是值相同。
六、關于調用異常
建議使用異常彙報錯誤,而不是傳回錯誤碼,異常資訊能攜帶更多資訊,并且語義更友好。
如果擔心性能問題,在必要時,可以通過 override 掉異常類的
fillInStackTrace()
方法為空方法,使其不拷貝棧資訊。
查詢方法不建議抛出受檢異常,否則調用方在查詢時将過多的
try...catch
,并且不能進行有效處理。
服務提供方不應将 DAO 或 SQL 等異常抛給消費方,應在服務實作中對消費方不關心的異常進行包裝,否則可能出現消費方無法反序列化相應異常。
七、參數檢查過濾
調用方及服務方都應該對輸入參數進行校驗。可以通過統一的攔截方式處理。
如通過檢查空值、參數長度等進行過濾,減少不必要的調用資源消耗及異常隐患,