當前位置: 妍妍網 > 碼農

如何優雅的實作介面統一呼叫

2024-02-29碼農

來源:juejin.cn/post/7276261829726191676


# 耦合問題

有些時候我們在進行介面呼叫的時候,比如說一個push推播介面,有可能會涉及到不同渠道的推播,以我目前業務場景為例,我做結算後端服務的,會與金蝶財務系統進行互動,那麽我結算後端會涉及到多個結算單型別,如果每一個種型別的結算單都去暴露一個contoller介面給前端提供,而且其實對接第三方的介面,有些介面是共通的;

# 前端涉及到的問題

  • 需要呼叫後端多個controller,不同介面不同的傳參數,如果遇到後端介面修改,會涉及到多個頁面的修改,耦合度很高;

  • 需要對多個按鈕設定許可權配置;


  • # 後端涉及到的問題

  • 需要每個業務介面,都去寫一個對接第三方介面的push推播方法,無形中增加很多重復的程式碼,耦合度也很高;

  • 如果涉及到第三方服務介面改造,後端介面也需要進行更改,會修改大量程式碼;


  • # 如何解決

    1. 建立對接第三方服務的微服務,站定為tps服務,該服務只作為一個後端微服務,與第三方服務進行對接,並且合理封裝呼叫參數,將公共參數提出進行封裝;

    2. 後端其余業務系統對接這個獨立的微服務,比如訂單、結算、供應商系統對接這個服務,由tps服務統一提供對接介面,其余服務實作這個tps提供的feign介面;

    3. 業務系統只需要關註service層業務的實作,無需處理對接的業務邏輯;

    大致的流程圖就是這樣的

    # 具體實作

    Tps服務

    Tps服務暴露feign介面,前端統一透過Tps提供的介面進行呼叫

    //對接第三方服務介面publicinterfaceIKingdeeManagementService {Boolean push(KingdeePushCO.Request request);}

    Feign介面實作類

    @Slf4j@Servicepublic classKingdeeManagementServiceImplimplementsIKingdeeManagementService{@Autowiredprivate ApplicationContext applicationContext;@Autowiredprivate KingdeeThirdSettingService kingdeeThirdSettingService;@Overridepublic Boolean push(KingdeePushCO.Request request){ KingdeeBusinessPushServiceEnum kingdeePushServiceEnum = KingdeeBusinessPushServiceEnum.getKingdeePushServiceEnumByType(request.getBusinessType()); IKingdeeBusinessPushService kingdeePushService = null;try { kingdeePushService = (IKingdeeBusinessPushService) applicationContext.getBean(kingdeePushServiceEnum.getClazz()); } catch (BeansException e) { log.error("當前型別暫未實作,請聯系開發");thrownew ServiceException("當前型別暫未實作,請聯系開發"); } R<Boolean> result = null; result = kingdeePushService.pushKingdee(request);returntrue;// } }}

    列舉類別定義

    publicenum KingdeeBusinessPushServiceEnum {private class clazz;private Integer type;privateString interFaceName;KingdeeBusinessPushServiceEnum( class clazz, Integer type, String interFaceName) {this.clazz = clazz;this.type = type;this.interFaceName =interFaceName;}RECEIPT_VOUCHER(IJaKingdeeBillClient. class,KingdeeBusinessTypeConstant.RECEIPT_VOUCHER, KingdeeSettingEnum.INTERFACE_TYPE_JA_RECEIPT_VOUCHER.getCode()),;}

    分別有clazz、type、interFaceName內容,

  • clazz定義為feign介面,業務系統提供的服務介面;

  • type前端需要傳的參數,不同的Integer值代表,不同的feign介面對映;

  • interFaceName第三方介面列舉,表示需要具體調哪個第三方介面;

  • 業務系統

    拿bms服務舉例說明:繼承Tps服務的feign介面,重寫push方法;

    Feign介面實作,透過factory工廠類初始化,不同的service實作類;

    JaKingdeeFactoryUtil 工廠工具類,獲取工廠例項,這裏其實也可以使用列舉對映,避免以後介面太多,需要寫很多case when;

    JaKingdeeServiceFactory是個介面,提供方法;

    實作上面的介面,透過單例工廠的模式double check的模式實作,並且加悲觀鎖,避免一個工作執行緒多次建立工廠例項,SpringContextUtils./getBean/獲取servcie例項,業務層只需要實作service介面,實作不同業務邏輯的push推播方法;


    # 總結

    這是我之前設計的關於介面統一呼叫的流程,當然其實還是包括對接第三方重復呼叫的問題、呼叫結果緩存、呼叫超時解決、失敗降級的一些策略,如果還有更好的介面統一呼叫方式歡迎大家評論區留言討論;

    熱門推薦