Skip to content

Golden Path — Schema (*.schema.ts)

TypeBox schemas describe request bodies, responses, and shared shapes. Registering them with fastify.registerSchema feeds HTTP validation and can feed generated shared types so backend and frontend can align on the same definitions where you choose to use them.

What we recommend structurally

For each datatype, keep a clear split so routes and future frontend validation can reuse the same pieces:

PieceRole
Base / full document schemaFields common to stored documents (often includes _id, timestamps).
CreateBody for POST — usually omits backend-generated fields.
UpdateBody for PATCH — optional fields only.
Delete / hard-deleteIf you expose delete semantics, separate narrow schemas keep routes honest.

Use stable $id / title metadata on each Type.Object so generated artifacts and OpenAPI-style tooling stay traceable. The cooking-step example below is the reference layout.

When you later add client-side validation in the docs, aim to reuse the same TypeBox definitions (or generated static types) so create/update payloads cannot drift between backend routes and UI forms.

Responsibilities

  • One schema module per datatype (or a deliberate split if a datatype is huge).
  • Export register…Schemas(fastify) and call it from the plugin index.ts.

Registering schemas from the plugin entry

Export register…Schemas(fastify) from your schema module and call it from the datatype or plugin index.ts alongside models, routes, and payload — same registration phase as the rest of the Golden Path.

typescript
registerExampleSchemas(fastify)

Replace Example with the PascalCase name of your datatype’s schema module. The cooking-step example shows the full TypeBox graph and this call in context.

Full example (base, create, update, registration)

The complete TypeBox layout (base, create, update, register…Schemas) lives in the cooking-step file — it has its own frontmatter, so we link instead of embedding (avoids a broken second --- block in this page):

See also