Integration patterns for government services
Integration is where government architecture quietly comes undone, usually because the cost of connecting systems gets underestimated right up to the point where it bites. This guide walks through the patterns, the trade offs, and the failure modes you will actually meet.
You'll come away with:
- How to choose an integration pattern that fits the context rather than the fashion
- The trade offs between point to point, hub, API, messaging, and event driven approaches
- When synchronous integration helps and when it quietly makes your service fragile
- How to deal with the legacy systems that government integration always seems to involve
- How to handle data transformation and error management so failures stay contained
Integration patterns: an overview
The main integration patterns, what they suit, and the questions that point you towards one.
The patterns themselves are not complicated. What trips people up is choosing one out of habit rather than on the evidence in front of them. Point to point feels sensible when you have two systems to join, and it stays sensible right up until you have eight, at which point the wiring diagram looks like a plate of spaghetti and nobody can change anything without breaking something else. A hub tidies that up by giving everything a single place to connect, but it comes with a quieter cost that rarely makes it into the design document: whoever owns the hub owns everyone else's ability to integrate, which in government is a political fact as much as a technical one. APIs, messaging and events loosen the coupling further, and they earn their keep as the estate grows, but each one adds infrastructure you then have to run. Start with the interaction you actually need, not the pattern you would most like to put on your CV.
Start with the interaction you need and the coupling you can afford. The right pattern falls out of that, not the other way round.
Synchronous and asynchronous: choosing the model
Whether the caller waits for an answer shapes user experience, resilience, and how much operational complexity you take on.
This is the decision people get wrong most often, usually because synchronous feels simpler and simpler feels safer. It is simpler, right until the system you are calling slows down or falls over, at which point your service inherits its problems. Call a thirty year old back office system synchronously and let it have a bad morning, and now your users are having one too. Asynchronous breaks that chain. You accept the request, hand back a reference number, and do the awkward work out of sight. The price is real, because you now have to think about messages that fail to arrive, arrive twice, or turn up in the wrong order, and you have to design the screen that says we will update you shortly without making anyone anxious. Most government services that work well are quietly hybrid. They are synchronous at the front door, where someone is waiting for an answer, and asynchronous in the back office, where the slow and unreliable integrations live.
Synchronous integration ties your availability to theirs. Sometimes that is fine. Often it is the reason your service goes down when something else does.
Government integration platforms and common components
Common components speed up delivery, and they also hand you dependencies and boundaries you need to design around.
Reaching for a common component before building your own is the right instinct, and it is also what the Technology Code of Practice expects of you. Notify, Pay, One Login and Forms exist precisely so that you are not rebuilding email delivery or card payments for the hundredth time across government. Use them. What the adoption pages tend to skip over is that every component you reuse becomes a dependency you now carry. If Notify has an outage, your service cannot send notifications, and no amount of clever code on your side changes that, so treat these as external systems with their own availability, their own rate limits, and their own edges. Pay handles the common payment flows well and then stops short of the unusual ones. You want to find those limits during design, when changing your mind is cheap, rather than at a service assessment, when it is not.
Reuse what fits. Just remember that anything you reuse becomes something you depend on and cannot control.
Legacy integration challenges
Older systems rarely behave like modern platforms, so the work is isolating their quirks and designing around their constraints.
In government, integrating with something old is not the exception, it is most of the job. There will be a system that predates your team, has no API, sends a file once a night, and behaves in ways nobody still employed can fully explain. You will not find those behaviours in the documentation, because there isn't any worth the name. You will find them in integration testing, three weeks before go live, in the shape of an error code that means one thing on Tuesdays and something else on Wednesdays. The practical move is to stop fighting this and contain it. Put an adapter between your service and the old world so all the strangeness lives in one place you control, and your new service only ever sees clean, modern data. Whether you call it a wrapper, an anti corruption layer, or scheduled synchronisation matters less than the principle behind it: the old system's quirks are a design input, and your job is to stop them leaking into everything else.
Treat the old system's quirks as a design input, not a nasty surprise, and keep them behind the adapter where they belong.
Data transformation and mapping
Connecting systems is the easy half. Getting them to agree on what the data means is the half that eats the timeline.
Connecting two systems is the straightforward part. Getting them to agree on what the data means is the part that quietly consumes your schedule. One system calls a person an applicant, the next calls them a claimant, a third calls them a customer, and somewhere a fourth has decided gender is recorded as one or two with no surviving note of which is which. Dates are the classic trap. They look trivial, then a time zone or a daylight saving boundary corrupts a batch and you lose a day working out why. The discipline that saves you is to keep all this mapping in one place at the boundary of your service rather than smeared through the code, and to translate everything to a single internal model so each external system needs only one set of mappings. Then test it with real data, including the ugly records, because transformation logic that sails through tidy samples tends to fall over the moment it meets production.
The connection is only half the work. The data still has to mean the same thing on both sides, and that is where the real effort hides.
Error handling in integrations
Failures are inevitable, so resilience comes down to how deliberately you detect, contain, and recover from them.
Everything you integrate with will fail at some point, so the useful question is not whether but how you respond when it does. A momentary network blip and a permanently rejected record need completely different treatment. A service that retries a genuinely broken request forever causes as much trouble as one that gives up on a request that would have worked on the second attempt. The rules that matter most in government are the ones with a citizen on the other end. Never drop data silently, because a swallowed payment is someone who did not receive money they were owed, and that turns into a complaint and then a headline. Never show a user the words something went wrong and walk away from it. Tell them what happened and what to do about it. And make your retries safe to repeat, so a message handled twice does not become a duplicate application or a second payment landing in someone's account.
Failure is normal. The quality of your error handling is usually what decides how reliable your service actually feels to the people using it.
Designing integration architecture for government
Good integration architecture is methodical: map the estate, choose patterns on evidence, design for failure, and plan for change.
Put all of this together and a method appears, and it is reassuringly dull. Map the estate first, because the integration you forget is the one that derails you in month four. Write down every system you exchange data with, what flows, in which direction, how often, through what interface, and who owns it. Classify each one, because the right pattern falls out of the classification rather than out of preference. Then give the whole lot somewhere to live, a dedicated integration layer that handles connection, authentication, transformation, retries, logging and monitoring in one place, so the messiness of the outside world stays out of your core service. Assume each integration will fail and decide now how that failure is spotted, explained and put right. Assume each one will change, because external APIs and data formats always do. None of this removes the difficulty of integrating in government, but it means you meet that difficulty on purpose, with a plan, rather than discovering it live in production with users watching.
Connecting systems is the easy part to picture. Keeping those connections working while the estate around them keeps shifting is the part that actually defines the architecture.