A core mainframe system with no API supports nightly batch file exchange only. The business needs near-real-time order status. Design the integration.
Show the full answer Hide the answer
Establish the real constraint
"No API" usually means no API the mainframe team will build on your timeline. Find out what exists: message queue interfaces, database access, transaction gateways, screen-scraping middleware. The available surface determines the design.
Assume here: nightly files plus read access to the underlying database.
The integration
Change data capture from the transaction log, not polling. CDC reads the log rather than querying tables, so it adds negligible load to the source — which is the decisive property when the source is a system nobody wants to touch and where a query can be a capacity event.
Stream changes into an event topic. This converts batch into near-real-time without any mainframe change, which is the whole point.
Keep the nightly file as reconciliation. Compare the CDC-derived state against the authoritative batch daily and alert on divergence. CDC has failure modes — missed changes, schema drift, replication lag — and the batch file is a free correctness check you already have.
The anti-corruption layer, which is the architectural core
CDC output carries the source's table and column names, encodings and historical oddities. It must not become the published contract.
Translate into a domain model your services own: meaningful names, proper types, decoded status codes, normalised dates. Publish that.
Without this layer, forty years of mainframe modelling decisions propagate into every new service, and the modernisation has failed before it starts.
Ownership rule: the translator is owned by whichever side changes less predictably — here, the side integrating with the fixed system.
Read model
Materialise a read-optimised store of order status, updated from the events. Queries hit that, never the mainframe. Serves the business need and decouples read load entirely.
Be explicit about staleness — seconds of lag — and confirm it is acceptable. For order status it almost always is; for a balance check before a transaction it may not be.
Writes
Harder, and worth separating in the answer. Options: a transaction gateway if one exists; a request queue the mainframe drains on its own schedule, with asynchronous status back to the caller; or continuing to write via batch while reads are real-time — an asymmetry that is often perfectly acceptable and much cheaper.
Trajectory
This is the strangler fig pattern. The event stream and anti-corruption layer are the seam that lets functionality move off the mainframe incrementally: new capabilities consume events rather than integrating directly, and each migrated capability is one fewer dependency.
Say plainly that the mainframe may never be fully retired — and that this design delivers value without requiring it to be.