Start with the number of systems

Two or three systems connecting directly is simple, understandable, and correct. The trouble is that direct connections grow with the square of the number of systems, and the point where that becomes unmanageable arrives sooner than teams expect.

If you can foresee more than a handful of participants, choose a structure that will not need unpicking later.

Decide whether the caller needs an answer

Some interactions genuinely need a synchronous response — a payment authorisation, a stock check at checkout. Many do not: notifying that an order was placed, updating a search index, sending a receipt.

Making everything synchronous couples the availability of every system together. Making everything asynchronous makes simple queries needlessly complicated. Classify each interaction rather than picking one style.

Understand what events buy and cost

Publishing an event lets a producer stay unaware of who consumes it, which means new consumers can be added without touching the producer. That is genuine decoupling and it is valuable.

The cost is that no single place describes what happens when something occurs, ordering becomes something you must think about, and tracing a problem across consumers requires tooling you have to build or buy.

Agree the failure behaviour first

This is where integrations actually break, and it is almost never in the interface specification.

  • What happens when the other side is unavailable — retry, queue, or fail?
  • Is a repeated message safe, and how is that guaranteed?
  • Does order matter, and is it actually preserved?
  • How long may a message be delayed before it is worthless?
  • Who is alerted when messages stop flowing, and how would anyone notice?

Version from the beginning

Message and API contracts change. Establishing versioning and a deprecation approach while there is one consumer costs nothing; adding it once there are eight is a project.

Contract tests in the pipeline catch accidental breakage far more reliably than documentation describing the contract does.

Make it observable

A correlation identifier that travels with every message, and metrics on throughput and lag, are what make an integration debuggable. Without them a stalled integration is discovered by a customer.

Build this in at the start; retrofitting it means changing every participant.

Written by the Global IT Solutions engineering team. Working through this decision right now?

Start a conversation