Solving Backend Coupling Issues with a Dedicated TPS Microservice

This article analyzes the high coupling caused by multiple backend controllers and third‑party push interfaces, then proposes a dedicated TPS microservice that encapsulates third‑party calls via Feign, standardizes parameters, and reduces code duplication for frontend and backend systems.

Architecture Digest
Architecture Digest
Architecture Digest
Solving Backend Coupling Issues with a Dedicated TPS Microservice

Coupling Problem

Sometimes when calling interfaces, such as a push notification interface, multiple channels need to be handled.

In my current business scenario, the settlement backend interacts with the Kingdee financial system. The settlement backend deals with several settlement order types, and exposing a separate controller for each type leads to many controllers, many of which share common third‑party interfaces.

Issues on the Frontend

Multiple controllers must be called with different parameters; any change in a backend interface requires modifications on many pages, resulting in high coupling.

Permission configuration is needed for many buttons.

Issues on the Backend

Each business interface needs its own method to push to the third‑party service, creating a lot of duplicated code and high coupling.

When a third‑party service interface changes, many backend interfaces must be updated.

Solution

Create a dedicated microservice (named TPS) that only handles communication with third‑party services, encapsulating common parameters.

Other business systems (order, settlement, supplier) call this TPS service via a unified Feign interface; they implement the Feign client provided by TPS.

Business systems focus on service‑layer logic and do not need to handle third‑party integration details.

The overall flow diagram is shown below:

Flow diagram
Flow diagram

Specific Implementation

TPS Service

The TPS service exposes a Feign interface that the frontend calls uniformly.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Consolas, Monaco, Menlo, monospace; font-size: 12px"><span style="color: #5c6370; font-style: italic; line-height: 26px"><span>//对接第三方服务接口</span></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>public</span></span><span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px"><span>interface</span></span><span style="color: #e6c07b; line-height: 26px"><span>IKingdeeManagementService</span></span></span><span>{</span><span><br/></span><span style="line-height: 26px"><span>Boolean </span><span style="color: #61aeee; line-height: 26px"><span>push</span></span><span style="line-height: 26px"><span>(KingdeePushCO.Request request)</span></span></span><span>;</span><span><br/></span><span>}</span><span><br/></span></code>

Feign interface implementation class:

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Consolas, Monaco, Menlo, monospace; font-size: 12px"><span style="color: #61aeee; line-height: 26px"><span>@Slf</span></span><span>4j</span><span><br/></span><span style="color: #61aeee; line-height: 26px"><span>@Service</span></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>public</span></span><span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px"><span>class</span></span><span style="color: #e6c07b; line-height: 26px"><span>KingdeeManagementServiceImpl</span></span><span style="color: #c678dd; line-height: 26px"><span>implements</span></span><span style="color: #e6c07b; line-height: 26px"><span>IKingdeeManagementService</span></span></span><span>{</span><span><br/></span><span><br/></span><span style="color: #61aeee; line-height: 26px"><span>@Autowired</span></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>private</span></span><span> ApplicationContext applicationContext;</span><span><br/></span><span style="color: #61aeee; line-height: 26px"><span>@Autowired</span></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>private</span></span><span> KingdeeThirdSettingService kingdeeThirdSettingService;</span><span><br/></span><span><br/></span><span style="color: #61aeee; line-height: 26px"><span>@Override</span></span><span><br/></span><span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px"><span>public</span></span><span> Boolean </span><span style="color: #61aeee; line-height: 26px"><span>push</span></span><span style="line-height: 26px"><span>(KingdeePushCO.Request request)</span></span></span><span>{</span><span><br/></span><span><br/></span><span>        KingdeeBusinessPushServiceEnum kingdeePushServiceEnum = KingdeeBusinessPushServiceEnum.getKingdeePushServiceEnumByType(request.getBusinessType());</span><span><br/></span><span><br/></span><span>        IKingdeeBusinessPushService kingdeePushService = </span><span style="color: #c678dd; line-height: 26px"><span>null</span></span><span>;</span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>try</span></span><span> {</span><span><br/></span><span>            kingdeePushService = (IKingdeeBusinessPushService) applicationContext.getBean(kingdeePushServiceEnum.getClazz());</span><span><br/></span><span>        } </span><span style="color: #c678dd; line-height: 26px"><span>catch</span></span><span> (BeansException e) {</span><span><br/></span><span>            log.error(</span><span style="color: #98c379; line-height: 26px"><span>"当前类型暂未实现,请联系开发"</span></span><span>);</span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>throw</span></span><span style="color: #c678dd; line-height: 26px"><span>new</span></span><span> ServiceException(</span><span style="color: #98c379; line-height: 26px"><span>"当前类型暂未实现,请联系开发"</span></span><span>);</span><span><br/></span><span>        }</span><span><br/></span><span>            R<Boolean> result = </span><span style="color: #c678dd; line-height: 26px"><span>null</span></span><span>;</span><span><br/></span><span>            result = kingdeePushService.pushKingdee(request);</span><span><br/></span><span><br/></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>return</span></span><span style="color: #c678dd; line-height: 26px"><span>true</span></span><span>;</span><span><br/></span><span style="color: #5c6370; font-style: italic; line-height: 26px"><span>//    }</span></span><span><br/></span><span>    }</span><span><br/></span><span>}</span><span><br/></span></code>

Enum definition:

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Consolas, Monaco, Menlo, monospace; font-size: 12px"><span style="color: #c678dd; line-height: 26px"><span>public</span></span><span style="color: #c678dd; line-height: 26px"><span>enum</span></span><span> KingdeeBusinessPushServiceEnum {</span><span><br/></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>private</span></span><span> Class clazz;</span><span><br/></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>private</span></span><span> Integer type;</span><span><br/></span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>private</span></span><span> String interFaceName;</span><span><br/></span><span><br/></span><span>KingdeeBusinessPushServiceEnum(Class clazz, Integer type, String interFaceName) {</span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>this</span></span><span>.clazz = clazz;</span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>this</span></span><span>.type = type;</span><span><br/></span><span style="color: #c678dd; line-height: 26px"><span>this</span></span><span>.interFaceName =interFaceName;</span><span><br/></span><span>}</span><span><br/></span><span>RECEIPT_VOUCHER(IJaKingdeeBillClient</span><span style="line-height: 26px"><span>.</span><span style="color: #c678dd; line-height: 26px"><span>class</span></span><span>,</span><span style="color: #e6c07b; line-height: 26px"><span>KingdeeBusinessTypeConstant</span></span><span>.</span><span style="color: #e6c07b; line-height: 26px"><span>RECEIPT_VOUCHER</span></span><span>, </span><span style="color: #e6c07b; line-height: 26px"><span>KingdeeSettingEnum</span></span><span>.</span><span style="color: #e6c07b; line-height: 26px"><span>INTERFACE_TYPE_JA_RECEIPT_VOUCHER</span></span><span>.</span><span style="color: #e6c07b; line-height: 26px"><span>getCode</span></span><span>()),</span><span><br/></span></span><span>;</span><span><br/></span><span>}</span><span><br/></span></code>

The enum contains three attributes: clazz – defines the Feign interface that the business system provides. type – the integer value the frontend passes; different values map to different Feign interfaces. interFaceName – the name of the third‑party interface to be invoked.

Business System

Using the BMS service as an example, it inherits the TPS Feign interface and overrides the push method.

BMS example
BMS example

The Feign implementation is initialized via a factory class, allowing different service implementations.

Factory initialization
Factory initialization

The utility JaKingdeeFactoryUtil obtains factory instances; an enum mapping could also be used to avoid many case statements. JaKingdeeServiceFactory is an interface that provides methods; its implementation follows a double‑checked locking singleton pattern with pessimistic locking to prevent multiple creations. SpringContextUtils.getBean retrieves service instances, and the business layer only needs to implement the service interface for different push logics.

Singleton factory
Singleton factory

Conclusion

This design presents a unified approach for invoking third‑party interfaces, addressing repeated calls, result caching, timeout handling, and fallback strategies; readers are invited to share alternative solutions.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendarchitecturefeignMicroserviceCoupling
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.