Most integration work should be done with off-the-shelf connectors. They’re cheaper, faster and someone else maintains them. We build custom middleware only when that path genuinely runs out.
It runs out in fairly predictable places: a legacy or sector-specific system with no modern API, transformation logic too complex to express in a visual builder, volumes where per-operation pricing becomes absurd, strict latency requirements, or data that can’t leave your environment for compliance reasons.
What we build in that situation:
- Integration services that handle the sync properly — incremental where possible, with change detection rather than full reloads.
- APIs over systems that lack them, giving other tools a clean, documented way in.
- Transformation and mapping layers where the two data models genuinely don’t line up.
- Queuing and retry so a downstream outage delays the sync instead of losing records.
- Idempotency, so a retry doesn’t create a duplicate — the failure mode that quietly does the most damage.
- Monitoring and alerting, because the worst integration failure is the silent one that’s been dropping five percent of records for a month.
We document the contract and hand over the source. Middleware nobody understands is a serious liability, and integration code is exactly the kind of thing that gets written once and then depended on for a decade.