A financial-data aggregator normalises hundreds of external bank APIs behind one interface. Where should the abstraction stop, and what happens when a provider does not fit?
Show the full answer Hide the answer
What the abstraction should cover
The common core that genuinely exists across providers: identity of the account, balance, transaction list with amount, date and description, and the operational concerns — authentication, refresh, error taxonomy. This is where normalisation delivers real value: a consumer writes one integration instead of hundreds.
Where it should stop
Anything where providers differ in ways that matter to the consumer. Transaction categorisation, pending versus posted semantics, balance definitions (available, current, ledger), date meanings (posted, transaction, value) and identifier stability all differ genuinely between institutions, and flattening them produces a number that is uniformly available and quietly wrong.
The pattern is to normalise the shape and preserve the provider's semantics alongside it — a normalised field plus the raw provider payload plus explicit metadata about what the value means. Consumers who need precision can reach through; consumers who need convenience take the normalised value knowing it is an approximation.
What happens when a provider does not fit
Three options, in order of preference:
- Extend the model if the difference is genuine and general. One provider revealing a distinction the model lacked usually means the model was wrong, not that the provider is odd.
- Expose it as provider-specific metadata, honestly labelled, rather than forcing it into a field where it does not belong.
- Mark the capability unsupported for that provider, which is far better than silently returning a plausible wrong value. A capability matrix per provider is a product feature, because consumers need to know what they can rely on.
The operational half that matters as much
Per-provider timeouts derived from that provider's own latency distribution, per-provider concurrency limits so one slow institution cannot consume every worker, per-provider circuit breakers tripping on latency as well as errors, and retry budgets bounded as a fraction of traffic.
One policy across hundreds of heterogeneous providers is guaranteed to be wrong for nearly all of them, and the failure it produces — one bank's slow afternoon becoming a platform-wide outage — is the characteristic incident in this domain.