Solving Interface Coupling with a Dedicated TPS Microservice
The article analyzes front‑end and back‑end coupling problems caused by multiple controller calls and third‑party push integrations, and proposes a dedicated TPS microservice that centralizes third‑party interactions via a Feign interface to reduce duplication and simplify future changes.
In many projects, front‑end pages need to call multiple back‑end controllers for different settlement types, leading to high coupling and duplicated code when third‑party push interfaces change.
Front‑end problems include the need to invoke many controllers with different parameters and to configure permissions for many buttons, causing tight coupling.
Back‑end problems include writing separate push methods for each third‑party service, duplicating code, and having to modify large amounts of code when third‑party APIs evolve.
Solution: create a dedicated microservice (TPS) that encapsulates all third‑party push interactions, exposing a single Feign interface for other services to call.
Steps:
Create the TPS microservice, define a Feign interface, and extract common parameters into a unified request object.
Other business services (order, settlement, supplier) call the TPS service via the Feign interface, delegating the push logic.
Business services focus only on their own service‑layer logic, without handling third‑party integration details.
Example Feign interface:
//对接第三方服务接口
public interface IKingdeeManagementService {
Boolean push(KingdeePushCO.Request request);
}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 enumVal = KingdeeBusinessPushServiceEnum.getKingdeePushServiceEnumByType(request.getBusinessType());
IKingdeeBusinessPushService service = null;
try {
service = (IKingdeeBusinessPushService) applicationContext.getBean(enumVal.getClazz());
} catch (BeansException e) {
log.error("当前类型暂未实现,请联系开发");
throw new ServiceException("当前类型暂未实现,请联系开发");
}
R
result = service.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 maps front‑end type values to specific Feign interfaces, allowing the factory to obtain the correct implementation without extensive case statements.
Factory utilities (JaKingdeeFactoryUtil, JaKingdeeServiceFactory) use double‑checked locking and pessimistic locks to ensure singleton creation of service instances.
Overall, the design reduces coupling, centralises third‑party integration, and simplifies future changes, while also providing a basis for caching, timeout handling, and fallback strategies.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.