Anti-corruption layers for Dynamics 365 integrations
How anti-corruption layers protect Dynamics 365 from external system model leakage — translation patterns, when to apply ACL, and the maintenance discipline.
When Dynamics 365 integrates with external systems, those systems have their own domain models, terminology, and quirks. Without intentional design, those external models leak into Dynamics — concepts named oddly, fields that don't match Dynamics's semantics, business logic intertwined. An anti-corruption layer (ACL) is the architectural pattern that prevents this leakage: a translation boundary that lets each side keep its own model clean.
The problem.
- External system A uses "Account" for what Dynamics calls "Customer."
- External system B has status codes "1, 2, 3, X, Y" with non-obvious meaning.
- External system C's date format differs.
- Each is a small thing; together they corrupt the model.
Without ACL, Dynamics ends up with foreign concepts; future maintenance pays the cost.
What an ACL provides.
- Translation — external concepts mapped to Dynamics concepts.
- Isolation — external system changes don't ripple into Dynamics.
- Defensive validation — external data validated before crossing.
- Abstraction — Dynamics doesn't depend on external's specifics.
The investment is real; the long-term maintenance benefit is greater.
Where to put the ACL.
- Azure Function — common Microsoft pattern.
- Logic App — for some scenarios.
- Custom service in App Service.
- API Management policies — for inbound translation.
- Plug-in — for simple cases.
For complex translations, dedicated services typically.
ACL responsibilities.
- Receive external system data.
- Validate — required fields, formats.
- Translate — to Dynamics model.
- Enrich — add Dynamics-specific defaults.
- Forward — to Dynamics API.
- Translate response back if needed.
The same in reverse for outbound.
Translation patterns.
- Field mapping —
external.CustomerId → dynamics.AccountNumber. - Value mapping —
external.Status "1" → dynamics.statecode 0. - Structural transformation — flatten / unflatten.
- Lookup translation —
external.CountryCode "US" → dynamics.Country reference.
Each translation is a documented rule.
Validation rules.
- Required fields present.
- Format valid — email, date, numbers.
- Value ranges — within expected.
- Business rules — domain validation.
Catch problems at the boundary; Dynamics doesn't process bad data.
Bidirectional ACL.
- Inbound translation (external → Dynamics).
- Outbound translation (Dynamics → external).
- Both managed in the ACL.
Symmetric translation; consistent model isolation.
When ACL pays back.
- Integration with legacy systems — old systems have unique models.
- Multiple similar external systems — multiple insurers, multiple banks; each slightly different.
- External systems that change frequently — ACL absorbs the change.
- Different teams own each system — ACL is the contract boundary.
When ACL is overkill.
- Simple, well-defined integration — direct mapping suffices.
- One-time data migration — overhead exceeds benefit.
- Low volume — manual quirks tolerable.
For most production integrations, some ACL exists even if minimal.
Implementation example.
External system "ProductFulfillment" sends shipments to Dynamics:
External payload:
{
"shipRef": "SHIP-12345",
"soNum": "SO-99",
"stat": "S",
"shipDate": "20261110"
}
Translated to Dynamics:
{
"shipmentTrackingNumber": "SHIP-12345",
"salesOrderId": "lookup-by-name(SO-99)",
"statusCode": 3, // Shipped
"shipmentDate": "2026-11-10T00:00:00Z"
}
The ACL does this translation; Dynamics never sees the foreign vocabulary.
Schema versioning. External system schemas evolve:
- ACL versioned independently.
- Multiple versions can coexist.
- Migration window for upstream callers.
Versioning enables schema evolution without breaking consumers.
Error handling at ACL.
- Validation errors — return to source; not propagated.
- Translation errors — log and alert; retry or dead-letter.
- Dynamics errors — translated back to source-friendly message.
The ACL prevents cryptic errors from reaching either side.
Monitoring ACL health.
- Throughput — messages translated.
- Validation failures — what's coming in bad.
- Latency — translation time.
- Errors — type and rate.
Standard observability; treats ACL as production service.
Common pitfalls.
- No ACL. External model leaks into Dynamics; foreign concepts proliferate.
- ACL as thin pass-through. Doesn't translate; just forwards. No protection.
- Hard-coded mappings. Should be configuration; making changes requires code.
- No validation. Bad data reaches Dynamics.
- Stateful ACL. State should typically live in Dynamics or external; ACL is stateless translation.
- Performance bottleneck. Heavy translation becomes throughput limit.
Patterns and frameworks.
- AutoMapper (.NET) — declarative object mapping.
- JSONata — JSON transformation language.
- JOLT — Java-based.
- Custom in TypeScript / C# — full control.
Choose based on team skill and translation complexity.
Testing.
- Unit tests — translation correctness.
- Property-based tests — round-trip preservation.
- Integration tests — with real external system.
- Performance tests — high-volume.
ACL is critical infrastructure; test like it.
Documentation.
- Field mapping documented.
- Value mappings referenced.
- Validation rules explicit.
- Error meanings explained.
Documentation enables maintenance years later.
Strategic positioning. Anti-corruption layers represent architectural maturity. Teams new to integration often skip ACL — direct mappings seem simpler. Teams with experience know the long-term cost of model leakage; they invest in ACL upfront.
For architects:
- Identify boundaries where ACL matters.
- Choose appropriate technology per boundary.
- Build versioning and observability.
- Document translations.
The investment pays back through:
- Cleaner Dynamics model.
- External system changes absorbed.
- Easier debugging.
- Lower maintenance over years.
Not every integration needs heavy ACL; every meaningful integration benefits from some level of intentional translation boundary. Design for the long term.
Related guides
- API Gateway patterns for Dynamics 365How API gateways enhance Dynamics 365 integration architecture — Azure API Management, security, rate limiting, transformation, and the patterns for managed API surfaces.
- CQRS pattern for Dynamics 365How CQRS (Command Query Responsibility Segregation) applies to Dynamics 365 architectures — write vs read separation, projection patterns, and when CQRS helps vs hurts.
- Event-driven architecture for Dynamics 365How to design event-driven integrations around Dynamics 365 — event sources, brokers, consumers, and the patterns that produce loosely coupled, scalable architectures.
- Eventually consistent integrations with Dynamics 365How to design and operate eventually-consistent integrations — consistency vs availability trade-offs, conflict resolution, and the UX implications.
- Idempotency in Dynamics 365 integrationsWhy integrations must be idempotent — patterns for safe retries, deduplication, correlation IDs, and the design principles that prevent duplicates and inconsistencies.