External Integration
Files Referenced in this Document
- IMyPluginNameExternalApi.cs
- MyPluginNameProjectService.cs
- CMSPluginEntry.cs
- appsettings.json
- CMSPluginMyPluginNameExtensions.cs
- CMSPluginMyPluginNameOptions.cs
- MyPluginNameWorker.cs
- IMyPluginNameFlowService.cs
Table of Contents
- Introduction
- HTTP API Integration Architecture
- Type-Safe RESTful Service Calls
- Project-Level Service Integration
- Authentication and Secure Communication Configuration
- Timeout and Error Handling Mechanisms
- Integration Testing Strategy
- Circuit Breaker and Resilience Design Suggestions
- Typical Integration Scenarios
- Conclusion
Introduction
This project integrates with external systems via HTTP API through the IMyPluginNameExternalApi interface, and coordinates project-level services through MyPluginNameProjectService. The system uses WebApiClientCore to implement type-safe RESTful calls, supporting flexible configuration management, state synchronization, and asynchronous processing mechanisms. This document details its integration capabilities, implementation mechanisms, and best practices.
HTTP API Integration Architecture
Diagram sources
Section sources
Type-Safe RESTful Service Calls
The system uses WebApiClientCore to implement type-safe HTTP calls, automatically generating client code through interface definitions, avoiding manual request construction and response parsing.
Interface Definition
The IMyPluginNameExternalApi interface defines the call contract for external services, using attributes to annotate HTTP methods and paths:
[HttpPost("api/v1/myPluginName/myEntityName")]
Task<MyEntityNameDto> CreateAsync([JsonContent] MyEntityNameCreateDto input);
This design ensures compile-time type checking and reduces runtime errors.
Dependency Injection Configuration
Register the interface via AddHttpApi<T> in CMSPluginEntry to achieve automatic injection:
context.Services.AddHttpApi<IMyPluginNameExternalApi>()
.ConfigureHttpApi(configuration.GetSection(nameof(IMyPluginNameExternalApi)));
Configuration is read from appsettings.json, supporting flexible environment adaptation.
Section sources
Project-Level Service Integration
MyPluginNameProjectService serves as a project-level service, responsible for coordinating state synchronization between local data and external systems, implementing cross-system business logic encapsulation.
Service Lifecycle Management
This service inherits from BaseProjectService and manages lifecycle by overriding StartAsync and StopAsync methods:
- On Start: Creates variable channel listener, subscribes to key variable changes
- On Stop: Releases resources and can trigger background jobs for cleanup
Variable Change Response Mechanism
Listens for specific variable changes via FlowVariableChannelListener, triggering events when monitored variable values change:
_channelListener.TagChanged += OnTagValueChanged;
Event handling uses asynchronous tasks to avoid blocking the main thread, ensuring system responsiveness.
External Call Coordination
In variable change handling, local persistence and external API calls can be coordinated:
Diagram sources
Section sources
Authentication and Secure Communication Configuration
HTTPS/TLS Configuration
Although the current configuration uses HTTP, the system supports HTTPS communication. It is recommended to use HTTPS in production environments:
{
"IMyPluginNameExternalApi": {
"HttpHost": "https://external-api.example.com/"
}
}
Ensure external services support TLS 1.2+ and configure certificate validation at the network layer.
Authentication Mechanism
The system declares that the service requires authentication via the AuthRequired property:
public override bool AuthRequired => true;
Actual authentication logic is handled by the platform base, usually including:
- JWT Token Validation
- API Key Validation
- OAuth2 Authorization
It is suggested to add authentication header support in the IMyPluginNameExternalApi interface:
[Header("Authorization", "Bearer {token}")]
Section sources
Timeout and Error Handling Mechanisms
Timeout Settings
WebApiClientCore supports configuring request timeouts, which should be defined in appsettings.json:
{
"IMyPluginNameExternalApi": {
"HttpHost": "http://127.0.0.1:18000/",
"Timeout": "00:00:30"
}
}
Or configured in code:
services.ConfigureHttpApi(config => {
config.Timeout = TimeSpan.FromSeconds(30);
});
Error Handling
The system adopts a layered error handling strategy:
- Call Layer: Capture exceptions and log
- Business Layer: Decide on retry or degrade based on error type
- Monitoring Layer: Record exceptions for alerting
private async Task ExecuteExternalApiAsync()
{
try
{
await _serviceProvider.GetRequiredService<IMyPluginNameExternalApi>().CreateAsync(dto);
}
catch (Exception e)
{
_logger.LogException(e);
}
}
It is recommended to implement retry mechanisms and circuit breaker protection.
Section sources
Integration Testing Strategy
The system provides complete test infrastructure to support verification of integration logic.
Test Architecture
- Unit Testing: Verify single method logic
- Integration Testing: Verify service collaboration
- End-to-End Testing: Verify complete business process
Test Base Class
MyPluginNameApplicationTestBase provides database context access capability, supporting data persistence verification in tests:
protected virtual void UsingDbContext(Action<CMSPluginDbContext> action)
Test Suggestions
- Mock External API: Use Moq or WireMock to mock external services
- Test Exception Paths: Verify handling of network timeouts, service unavailability, etc.
- Verify State Synchronization: Ensure local data is eventually consistent with external systems
- Performance Testing: Evaluate system performance under high concurrency
Section sources
Circuit Breaker and Resilience Design Suggestions
Although the current code does not directly integrate Polly, it is recommended to add circuit breaker mechanisms to improve system resilience.
Polly Circuit Breaker Strategy Suggestions
// Timeout + Retry + Circuit Breaker
Policy
.Handle<HttpRequestException>()
.Or<TimeoutException>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 3,
durationOfBreak: TimeSpan.FromSeconds(30)
);
// Exponential Backoff Retry
Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
);
Integration Methods
- Decorator Pattern: Create wrapper class to implement circuit breaker
- AOP Aspect: Inject resilience logic via interceptors
- Service Proxy: Add policies before
IMyPluginNameExternalApicalls
Monitoring Suggestions
- Log circuit breaker state changes
- Set alert thresholds
- Provide management interface to view circuit breaker status
Section sources
Typical Integration Scenarios
Integration with ERP System
Application Scenario: Synchronize to ERP system when production order changes.
Integration with MES System
Application Scenario: Real-time synchronization of device running data to MES.
Integration with Other CMS Modules
Application Scenario: Cross-module content collaborative editing.
Section sources
Conclusion
External integration in the backend template is centered on type-safe HTTP clients, project-level service coordination, and clear resilience boundaries. Use configuration-driven endpoints, authenticated communication, integration tests, and retry or circuit breaker policies to keep cross-system workflows observable and maintainable.