Decoupling Backend Services with a Dedicated TPS Microservice

The article examines coupling problems caused by multiple backend controllers and third‑party push interfaces, proposes a dedicated TPS microservice that centralizes third‑party calls via Feign, outlines its implementation with Java code, enums, factories, and demonstrates how this reduces duplication and improves maintainability.

Top Architect
Top Architect
Top Architect
Decoupling Backend Services with a Dedicated TPS Microservice

Coupling Issues

When calling interfaces such as a push notification, different channels may be involved. In my current scenario, the settlement backend interacts with the Kingdee finance system and handles multiple settlement types, leading to many controller endpoints and duplicated code.

Problems on the Front End

Multiple controllers need to be called; changes in backend APIs require modifications on many pages, resulting in high coupling.

Permission configuration is needed for many buttons.

Problems on the Back End

Each business interface must implement its own method to push to the third‑party service, causing code duplication and high coupling.

When third‑party APIs change, a large amount of backend code must be modified.

Solution

Create a dedicated microservice (named tps) that only handles communication with the third‑party service and encapsulates common parameters.

Other business systems (order, settlement, supplier) call this tps service via a unified Feign interface; the tps service provides the actual implementation.

Business services only need to focus on their own service‑layer logic without dealing with third‑party integration.

Overall flow diagram:

TPS flow diagram
TPS flow diagram

Specific Implementation

Tps Service

The tps service exposes a Feign interface that the front end calls uniformly.

//对接第三方服务接口
public interface IKingdeeManagementService {
    Boolean push(KingdeePushCO.Request request);
}

Feign implementation class:

@Slf4j
@Service
public class KingdeeManagementServiceImpl implements IKingdeeManagementService {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private KingdeeThirdSettingService kingdeeThirdSettingService;

    @Override
    public 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("当前类型暂未实现,请联系开发");
            throw new ServiceException("当前类型暂未实现,请联系开发");
        }
        R<Boolean> result = null;
        result = kingdeePushService.pushKingdee(request);
        return true;
    }
}

Enum definition:

public enum KingdeeBusinessPushServiceEnum {
    private Class clazz;
    private Integer type;
    private String interFaceName;

    KingdeeBusinessPushServiceEnum(Class clazz, Integer type, String interFaceName) {
        this.clazz = clazz;
        this.type = type;
        this.interFaceName = interFaceName;
    }

    // example entry
    RECEIPT_VOUCHER(IJaKingdeeBillClient.class,
        KingdeeBusinessTypeConstant.RECEIPT_VOUCHER,
        KingdeeSettingEnum.INTERFACE_TYPE_JA_RECEIPT_VOUCHER.getCode()),
    ;
}

The enum fields mean: clazz: the Feign interface provided by the business system. type: integer value passed from the front end to map to a specific Feign interface. interFaceName: name of the third‑party interface to be called.

Business System

For example, the BMS service inherits the Feign interface from the tps service and overrides the push method.

Business system example
Business system example

Feign interfaces are obtained via a factory class (JaKingdeeFactoryUtil) to avoid large case‑when statements.

Factory usage
Factory usage

The factory implements a double‑checked singleton pattern with pessimistic locking to ensure a single instance per thread.

Singleton factory
Singleton factory

Conclusion

This design unifies third‑party calls, reduces code duplication, lowers coupling, and can be extended with caching, timeout handling, and fallback strategies.

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.

BackendarchitecturefeignCoupling
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

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.