A communications API platform finds that adding a new messaging channel requires coordinated changes in the gateway, the billing service, the webhook dispatcher and the console UI, across four teams. What would you change about the coupling, and what should you deliberately leave alone?
Show the full answer Hide the answer
Reading the symptom correctly
The symptom is not "four services". It is that one business event — a new channel — has four implementations of the same knowledge. Each service holds the enumerated list of channels. That is content coupling dressed up as service boundaries.
Note what the symptom is not: not slow, not unreliable, not expensive to run. Expensive to change. Coupling is a change-cost property, and it is invisible on every dashboard you own.
What to change
Make the channel a data-plane concept. A channel becomes a registered descriptor — capabilities, message schema, rate limits, price-book reference, delivery-receipt semantics — that the platform reads. Adding a channel becomes configuration plus one adapter, not four deployments.
Give the gateway a canonical internal message contract. Every provider adapter translates into it. Downstream services couple to the canonical contract, which changes rarely, instead of to provider peculiarities, which change constantly. This is an anti-corruption layer and the highest-leverage boundary on the platform.
Make billing consume events, not enumerations. A billable event carries its own price-book key; billing stops needing to know what channels exist.
Drive the console from the registry, so the UI renders the channels the platform reports.
What not to change
- Do not merge the services. They are separated correctly — different scaling profiles, failure tolerances and on-call rotations. The boundaries are fine; the contract across them is wrong. Merging trades a change-cost problem for an operational one.
- Do not abstract provider differences away entirely. Some are real and load-bearing: delivery receipts that never arrive, per-country regulatory identifiers, per-provider throughput ceilings. An abstraction that hides those produces silent incorrectness, which is worse than the coupling. Model them explicitly as capabilities and let callers ask.
The principle
The right question is never "how many services touch this?" but "how many places must change together, and do they change for the same reason?" Four services that change together for one reason are one badly-drawn service. Four that change independently are four services.