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, reducing runtime errors.
Dependency Injection Configuration
Register the interface in CMSPluginEntry via AddHttpApi<T> for 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 acts 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 its lifecycle by overriding StartAsync and StopAsync methods:
- On Start: Creates a variable channel listener and subscribes to key variable changes.
- On Stop: Releases resources and can trigger background jobs for cleanup.
Variable Change Response Mechanism
Uses FlowVariableChannelListener to listen for specific variable changes, triggering an event when monitored variable values change:
_channelListener.TagChanged += OnTagValueChanged;
Event handling employs asynchronous tasks to avoid blocking the main thread, ensuring system responsiveness.
External Call Coordination
In variable change handling, coordination between local persistence and external API calls can be managed:
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 Verification
- OAuth2 Authorization
It is recommended 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 them.
- Business Layer: Decide retry or degradation based on error type.
- Monitoring Layer: Log 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 testing infrastructure to support verification of integration logic.
Test Architecture
- Unit Tests: Verify individual method logic.
- Integration Tests: Verify service collaboration.
- End-to-End Tests: Verify complete business flows.
Test Base Class
MyPluginNameApplicationTestBase provides database context access capabilities, supporting verification of data persistence in tests:
protected virtual void UsingDbContext(Action<CMSPluginDbContext> action)
Test Suggestions
- Mock External API: Use Moq or WireMock to simulate external services.
- Test Exception Paths: Verify handling of network timeouts, service unavailability, etc.
- Verify State Synchronization: Ensure eventual consistency between local data and external systems.
- Performance Testing: Evaluate system performance under high concurrency.
Section sources
Circuit Breaker and Resilience Design Suggestions
Although Polly is not directly integrated in the current code, it is recommended to add circuit breaker mechanisms to improve system resilience.
Polly Circuit Breaker Strategy Suggestion
// 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 classes to implement circuit breaking.
- AOP Aspect: Inject resilience logic via interceptors.
- Service Proxy: Add strategies before
IMyPluginNameExternalApicalls.
Monitoring Suggestions
- Log circuit breaker state changes.
- Set alert thresholds.
- Provide management interfaces to view circuit breaker status.
Section sources
Typical Integration Scenarios
Integration with ERP System
Application Scenario: Synchronize to ERP system when production orders change.
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
This project implements type-safe external system integration via WebApiClientCore. IMyPluginNameExternalApi provides clear RESTful call interfaces, and MyPluginNameProjectService encapsulates complex cross-system business logic. The system supports flexible configuration, comprehensive error handling, and a scalable integration architecture. It is recommended to further enhance circuit breaker mechanisms, perfect monitoring systems, and enforce HTTPS communication in production environments to ensure integration reliability and security.