Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Shape Checks at the Boundary

A function that accepts unknown and returns a typed value must validate the shape. Validation libraries (Zod, Yup, io-ts, Effect Schema) have proliferated; each works well in isolation; coupling the domain to one of them is the move teams regret two years later when they want to swap. @frenchexdev/ddd-schema-validation reifies schema validation as a port with a Zod adapter so the domain's call sites stay stable while the library underneath is replaceable.


What ddd-schema-validation Reifies

The port reifies one operation: given an unknown input, return either a typed value or a typed failure. The library underneath decides how the schema is declared (Zod's chainable API, Yup's object schemas, custom JSON Schema), but the port's signature is the same: parse(input: unknown): Result<TParsed, ValidationFailure>.

The discipline reflects the corpus's Port/Adapter discipline. Schema validation is infrastructure — it deals with foreign byte shapes coming in from outside the domain. The domain's job is to reject malformed inputs before they reach an aggregate constructor; the schema-validation port is the place that rejection happens.

The pattern is small. The runtime declares the port shape. The Zod adapter implements parse against Zod schemas. A future Yup adapter would implement the same parse against Yup schemas. The aggregate's caller (an application service, a factory, an HTTP route handler) invokes the port without knowing which adapter is wired.


The Runtime: ddd-schema-validation and adapter

Two packages — ddd-schema-validation and ddd-schema-validation-zod-adapter — both M4/M5 stubs pinned to SchemaShapeValidationRequirement. Zod is the chosen first substrate — TypeScript-native, decent error shapes, widely adopted.


  • Invoked by @Adapter at boundary points — every HTTP route, message-bus handler, file ingest pipeline parses input through the port before it reaches domain code.
  • Used by @Factory for input shape checks; the factory's start(...) method takes raw inputs, validates them through the schema port, then proceeds.
  • Composes with @DesignByContract — schema validation is the shape precondition; DbC's @Pre is the value precondition that runs on already-shape-valid inputs.
  • Lives behind @Port/@Adapter; the conformance suite verifies that adapters produce the same typed failures for the same inputs across substrates.

Back to the series index.

⬇ Download