PATTERN Cited by 1 source
Client-side schema validation¶
Validate events against schemas in a shared client library, on the publisher / subscriber side, rather than via a centralized validation service on the runtime path. Publishers catch malformed events before they're emitted; subscribers catch contract violations before they're processed; no extra network hop is added to the runtime critical path.
Shape¶
- Schema source of truth — a schema registry holding versioned event definitions.
- Build-time code bindings — the registry exposes schemas as generated code bindings (classes, structs, types) so publishers construct events type-safely.
- Shared client library — a library every publisher + subscriber depends on. Four responsibilities:
- Type-safe event construction — wraps generated bindings behind idiomatic constructors.
- Pre-publish validation — on
publish(event), validates the event against its schema; fails fast if malformed. - Serialization + transport — handles the actual wire interaction with the event bus.
- Subscriber-side deserialization — presents incoming events to subscribing services in ready-to-use form.
- Single integration-error surface — errors surface in the client's own type system / exception types at development time rather than being discovered in production.
Why not centralized validation?¶
Amazon Key's team named this trade explicitly:
| Centralized validation service | Client-side validation | |
|---|---|---|
| Runtime latency | Extra network hop | None |
| Infra scaling | Own service, own scaling problem | Piggybacks on publisher/subscriber |
| Developer feedback | At runtime (maybe in a staging env) | Immediate, in the IDE / build |
| Operational burden | Yet another managed service | Library version bumps |
| Availability | New dependency to keep up | No new dependency |
| Consistency | Guaranteed uniform validator | Requires library-version discipline |
The centralized option's only win is uniform enforcement — but that can be achieved by making the client library the only permitted publisher path (e.g. enforce via IAM / bus resource policy that only the library's publish role may put events on the bus) without paying the runtime-hop tax.
Required capabilities¶
- Registry with build-time code-binding generation. Without this, developers hand-write classes that drift from schemas.
- Library-version governance. Because the library is the enforcement surface, out-of-date libraries = out-of-date validation. Either pin + auto-bump via CI, or block old versions at the IAM layer.
- Schema-evolution compatibility rules enforced at registry PR time (so a breaking change doesn't escape into a published schema against which some services still validate with older rules).
- Error surface that's actionable: "field
Xmissing" beats "schema validation failed" beats "invalid input".
Tradeoffs¶
- Only as strong as the library's adoption. A team that bypasses
the library can publish whatever it wants. Mitigate by authorizing
only the library's role to publish — raw
PutEventsblocked. - Library-version drift. Consumer using a newer library validates against a newer schema than a publisher using an older library expects. Requires explicit versioning strategy (pin major, auto-bump minor; or force all-services-at-head).
- Doesn't catch semantic invariants that aren't schema-expressible
(e.g. "the
timestampmust be in the last 24h", "theuser_idmust exist"). Those remain application-level concerns. - Doesn't replace contract testing between publisher and subscriber; consumer-driven contract testing (Pact-style) is complementary.
Why it matters¶
- Immediate developer feedback. The whole point: catch the bad
event at
publish(), not after it's been fanned out to N consumers. - No runtime network hop. Validation happens in-process; event bus sees only valid events.
- Standardization point for non-validation concerns. Once the client library exists, it becomes the natural place for event ID generation, clock skew handling, retries, tracing-header propagation, and DLQ behavior. Amazon Key credits their client library with "addressing 90% of common integration errors."
Seen in¶
- sources/2026-02-04-aws-amazon-key-eventbridge-event-driven-architecture — Amazon Key built a shared client library wrapping their custom JSON-Schema Draft-04 repository over EventBridge. Library handles code bindings, pre-publish validation, serialization + publishing, and subscriber-side deserialization. Reported: 90% of common integration errors caught by the library; new publisher/subscriber integration time 40h → 8h.
Related¶
- concepts/schema-registry — the substrate this pattern requires.
- concepts/event-driven-architecture — the architectural style this pattern supports.
- systems/amazon-eventbridge — the event bus that doesn't natively validate, making this pattern necessary.
- patterns/single-bus-multi-account — the org-scale deployment topology this pattern integrates with; the library is shared across all service-team accounts.
- patterns/reusable-subscriber-constructs — sibling client-library pattern on the infrastructure side.