Engineering

Legacy System API Integration: A Migration Plan You Can Actually Test

Connecting a new product to an old system is a data ownership and cutover problem before it is an endpoint problem. Here is the contract, access model and rollback test to put in the brief.

Legacy system API integration sounds like an endpoint project until the first duplicate order, stale customer balance or authorization leak. The older application may be awkward to change, but it is usually still the place where the business decides what is true. A new API does not remove that responsibility. For a CTO commissioning an integration, the first deliverable should be a map of who owns each record and each write, followed by a cutover that can be reversed.

This guide is for a company connecting an existing ERP, line-of-business application or database to a new portal or service while the old system keeps operating. It is narrower than a general custom portal build and more operational than our REST API engineering guide. The question is not how quickly a developer can expose data. It is how both systems behave on the day one of them is late, wrong or unavailable.

Put this sentence in the project brief: for every business object, name the system of record, the permitted writers, the conflict rule and the rollback path. If any column is blank, the API contract is not ready.

Start with the system of record, not the endpoints

Inventory the business objects that cross the boundary: customers, stock, orders, invoices, permissions and audit events. For each one, record its authoritative system today, the proposed owner after migration, which system may create or update it during the transition, and how quickly the other side must see a change. A dashboard may tolerate delayed stock totals; an order acceptance path may not. Those are business decisions, not framework settings.

ObjectQuestion to settleAcceptance evidence
CustomerWhich system assigns the durable identifier?Create, merge and duplicate cases keep one mapped identity
OrderWhich system may accept a new order during cutover?A retried request creates one order and one acknowledgement
InventoryIs the value a live reservation or a delayed snapshot?A stale read cannot promise unavailable stock
PermissionWhere is tenant and role membership authoritative?A user from tenant B cannot read tenant A through either API
Audit eventWhich service records the actor and correlation ID?A support engineer can trace one action across both systems
The object inventory is a better starting artifact than a list of REST routes.

Do not let a reporting copy quietly become a second writer. If both databases accept edits to the same field, define a conflict rule before building synchronization. Otherwise a late event can overwrite a newer decision. Where only read access is needed, a read-only integration can often deliver value without transferring ownership. That is a sensible first release when the legacy application is fragile.

Choose an adapter, a new service or a replacement deliberately

An adapter can translate a legacy protocol or data shape into a stable contract for new consumers. Microsoft’s anti-corruption layer pattern, read 14 October 2026, describes this boundary as a way to prevent an older model from spreading into a newer one. Translate vocabulary and error states here; do not make every new client understand an undocumented status code from the old system.

An adapter is useful when the old system remains authoritative. A new service is justified when a bounded capability can own its data and release cycle. Replacing everything at once requires a different risk budget. AWS’s strangler fig guidance, read 14 October 2026, describes incremental routing from a monolith to new services and names the proxy as a possible bottleneck or point of failure. That is a reason to test the routing layer under failure, not merely draw it in an architecture diagram.

  • Wrap it when consumers need a supported contract but the legacy application still owns the workflow.
  • Extract one capability when its data, rules and consumers can be separated without shared writes.
  • Replace it when the old system can be retired through a tested migration and the new owner can run the full business process.

Treat reads, writes and events as different contracts

A read endpoint needs a freshness promise: live, cached for a stated interval or refreshed after an event. A write endpoint needs an identity for the command, a clear success state and an answer for retry after timeout. An event needs a version, a durable identifier and a consumer that tolerates delivery more than once. The same JSON field can appear in all three places while meaning different things.

For a write that updates a database and publishes an event, avoid assuming both operations succeed together. Chris Richardson’s transactional outbox pattern, read 14 October 2026, records the event with the business transaction for later publication. It also notes that a relay may publish more than once, so the receiving side must be idempotent. Specify that behavior in the contract instead of calling the queue reliable and leaving duplicate handling undefined.

BoundaryContract questionFailure test
ReadHow old may the answer be?Pause synchronization and show the age of the displayed value
CommandWhat identifies the intended action?Repeat the same request after a timeout and observe one business effect
EventWhat happens on duplicate or out-of-order delivery?Replay the event and verify the state remains correct
ReconciliationHow is drift detected and repaired?Change a source record, drop an event and run the repair job
A contract is complete when its failure behavior is observable.

Authorization must survive the new route

Putting an API in front of a legacy database can bypass the application rules that previously guarded it. Require authorization at the object level, not only a successful login or a broad service token. The OWASP API Security Top 10 entry on broken object level authorization, read 14 October 2026, explains why endpoints that accept object IDs need an access check for each object. Test a known ID from another customer through every new read, update, export and attachment route.

A service account may be necessary to reach the old system, but it should not turn every caller into a superuser. Carry the human actor, tenant context and correlation ID across the boundary, then enforce the business permission before the privileged call. If the old system cannot express the same policy, the adapter must reject requests it cannot safely authorize. The detailed tenant model belongs in our customer portal security guide; this migration must prove that model still holds through the legacy route.

Stage cutover so rollback is a rehearsed operation

Begin with observation: compare the new adapter’s answers with the existing user path without allowing the new code to write. Then release a narrow read use case, measure mismatches, and only after that move one bounded write path. Keep routing decisions visible in configuration and log which system served each request. A feature flag is useful only if reversing it leaves data in a state the old path understands.

AWS’s strangler guidance also warns that data synchronized between the monolith and extracted services may be eventually consistent. Decide which screens may show that lag and which must stay on the authoritative path. If a new service has already accepted writes, rollback may require replay or reconciliation rather than just changing a route. Rehearse that before moving production traffic, with named owners and a stop condition for each stage.

  • Route a small, identifiable cohort to the new read path and compare responses with the old path.
  • Exercise timeouts, malformed responses, duplicate requests and an unavailable legacy dependency.
  • Record the metrics that trigger rollback: failed commands, reconciliation drift and authorization denials.
  • Run the rollback procedure in a non-production environment with representative data before cutover.
  • Retire the adapter only after every consumer and retained data obligation has a new owner.

Write acceptance tests before asking for an estimate

A proposal should identify the legacy interface, access to a representative test environment, object ownership, the target contract, data migration scope, monitoring, reconciliation and who operates the bridge after launch. If nobody can provide a test environment or a way to extract source data, that discovery work belongs in the estimate. Avoid a fixed timeline that assumes undocumented fields and business rules will behave as advertised.

Ask the engineering team to demonstrate one complete transaction in both directions, a denied cross-tenant request, a timed-out dependency, a repeated command, a dropped event, a reconciliation run and a rollback. Include the resulting logs and runbook in handover. Our documentation portal commissioning guide uses the same principle: sign off observable behavior rather than screens. For the wider build context, see delivered work and services.

The best first milestone is usually a thin, live integration with one business object and a real failure drill. It exposes the missing assumptions while the scope is still small. If your team is planning such a cutover, send us the systems involved, the object to move first and the constraint that keeps the old application live. That is enough for a useful technical scoping conversation.

What is legacy system API integration?

It is a supported interface between an older application and new software, with explicit rules for data ownership, access, freshness, writes and failure. A wrapper alone does not modernize the underlying workflow.

Can a legacy system be modernized without replacing it?

Yes. An adapter can expose a stable contract while the old system remains authoritative. Individual capabilities can then move when their data ownership and rollback path are clear.

What is the strangler fig pattern?

It is an incremental migration approach in which selected requests move from a monolith to new services over time. Routing, dependency failure and data synchronization need explicit testing during the transition.

How do you avoid downtime during a legacy integration cutover?

Stage a read-only comparison first, move a narrow cohort, define freshness and rollback conditions, rehearse failure cases and move writes only when reconciliation is proven. Zero downtime is a target to verify, not a promise from an architecture diagram.

Need help building this?

Let our team build it for you.

Dude Lemon builds production-grade web apps, APIs, and cloud infrastructure. Get a free consultation and project proposal within 48 hours.

Start a project