In 1980 Jon Postel wrote into the TCP specification: be conservative in what you do, be liberal in what you accept from others. Tolerant Reader applies this robustness principle to integration. A consumer reads only the fields it uses, ignores the rest, and treats absent optional data as a case to handle, not an error. Strict schema binding does the opposite, turning every producer-side addition into a consumer-side parse failure.

Tolerance applies to structure the consumer never reads, not to values it does read. Producers still owe additive-only discipline, pinned down by consumer-driven contract tests.

Tolerant Reader: a producer's payload grows from four fields to six; the tolerant reader binds only the four fields it uses, ignores the additions, and keeps working — no consumer deployment needed. A new value in an enum field it does read fails loudly instead of defaulting silently.

How It Works

  • Bind only a subset DTO of the fields the consumer uses; configure the deserializer to ignore unknown properties (e.g. Jackson’s ignoreUnknown).
  • Path extraction (JSON pointer, XPath) serves the same end for document-oriented formats.
  • An unknown value in an enum field the consumer does read is an error: reject, alert, or route to a manual fallback queue — never a silent default.
  • Apply explicit defaults for absent optional elements; fail only when required data is missing or invalid.
  • Validate the extracted values — types, ranges, invariants — not the document structure around them.

Failure Modes

  • A producer renames a field: the reader substitutes its default and processes wrong data without an error; drift surfaces downstream.
  • A new enum value falls back to a default: a PARTIALLY_REFUNDED payment reads as unpaid, and refund logic misfires.
  • Tolerance masks producer bugs: malformed payloads that a strict parser would reject flow into the domain.

Verification

  • Contract tests run each consumer against current and previous producer schemas; all pass (CI gate per release).
  • Unknown-field injection passes with zero errors; an injected unknown enum value lands in the fallback path, never a silent default.
  • Production monitors the default-substitution rate per field; an alert past a threshold (e.g. > 1% of messages) signals contract drift.
  • Schema registry with compatibility rules — rejects breaking producer changes at publish time, complementing consumer-side tolerance with a producer-side gate.

Example

A payment provider’s webhook initially sends id, amount, currency, and status. The shop’s reader binds exactly those four fields to a small DTO, unknown properties ignored. Over two years the provider adds fee_breakdown, risk_score, and a nested metadata object — the shop deploys nothing. When the provider later renames status to state, a breaking change, the contract tests catch it before production does.

References