design·lab

Design approach

Schema-Driven Development

Define the data shape once as a schema, then generate every other representation — types, validators, client, docs — from that single source.

✗ The problem

The same shape, defined by hand, four times

Server validation, client types, docs, and tests each re-describe the API shape separately. Nothing keeps them in sync.

// server validation (hand-written)
if (!body.email) reject("email required");

// client type (hand-written, drifted)
type User = { id: number; email?: string };

// docs (hand-written, stale)
// "email is optional" ← wrong! server requires it
Docs say optional, the server says required, the client type allows undefined — three sources of truth, three different answers.
✓ The approach

One schema, everything else generated

Write the schema once (OpenAPI / JSON Schema / GraphQL SDL / Protobuf). A generator turns it into validators, types, client SDK, and docs — contract-first. Change the schema → regenerate → everything stays in sync.

Schema
single source of truth
→ generates →
Types
Validation
Client
Docs
✓ See it live

Edit the schema — everything regenerates together

Change the User schema below. The generated TS type, the validation rule, and the doc snippet all update from the same source.

Schema (source of truth)

Generated: TS type

Generated: validation

Generated: docs

✓ Takeaway

The schema is the contract

  • One source of truth — the shape is described exactly once (DRY).
  • Contract-first — front-end and back-end teams build in parallel against the same schema before either implementation exists.
  • Can't drift — generated code is regenerated from the schema, not hand-copied.
  • Machine-checkable — a CI step can diff "generated vs. committed" to catch stale code automatically.
  • Caution: the schema becomes a coupling point across every consumer — version it and treat breaking changes like a public API change.
🎯 Relates: a pure application of DRY — the schema is the single source of truth; the generated client/validator is a generated Adapter to that contract.