Define an entity once, derive every request shape
Declare a resource schema once and derive the create body, update body, and query filter with your validator’s own .omit()/.partial()/.pick() — no StitchAPI-specific schema layer.
Task
You have a resource — a User — with the usual CRUD endpoints. You want to
describe its shape once and derive the create body (no server-assigned
fields), the update body (every field optional), and a query filter from that
one definition — without retyping fields and without learning a
StitchAPI-specific schema type.
Example
Your validator already does this. Define the entity with your schema library,
then derive the request shapes with its own composition methods and hand each
one to a stitch through toValidator().
import { , } from 'stitchapi';
import { } from 'zod';
// Define the entity once — one source for the runtime schema and the TS type.
const = .({
: .(),
: .(),
: .(),
: .(),
});
type = .<typeof >;
// Derive request shapes with the validator's own methods — not a StitchAPI layer.
const = .({ : true, : true }); // drop server-assigned fields
const = .(); // every field optional
const = .({ : true }).(); // optional ?email= filter
const = 'https://api.example.com';
const = <[]>({
: 'GET',
,
: '/users',
: { : () },
: (.()),
});
const = <>({
: 'POST',
,
: '/users',
: { : () },
: (),
});
const = <>({
: 'PATCH',
,
: '/users/{id}',
: { : () },
: (),
});NewUser, UserPatch, and UserFilter all trace back to the one User
schema — rename a field there and every derived shape, every stitch, and the
User type move with it.
How it works
.omit(), .partial(), and .pick() are your validator's methods, not
StitchAPI's. The runtime never sees them — it only ever calls validate()
through the Validator that toValidator()
produces, so each derived schema is just another schema as far as a stitch is
concerned. One z.object({...}) definition then feeds three things at once: the
runtime validation on every slot (query, body, output), and — via
z.infer — the User TS type the stitch<T> generic uses.
This is not StitchAPI-specific. Valibot, ArkType, and Effect Schema each
ship their own composition (v.partial, .pick, .omit, .and); the recipe
is identical, only the method names change. Any
Standard Schema validator goes
through the same toValidator() call.
Why there's no pattern primitive. StitchAPI deliberately does not
ship its own schema type with .partial()/.pick()/.omit() — that would
re-implement a validator inside a validator-agnostic core. The schema
library you already use owns composition; StitchAPI consumes the result. The
full reasoning is recorded in ADR
0011
— schema reuse is the validator's job.
See also
Send JSON and get a typed result back
POST a validated body and read a typed, runtime-validated result — input checked before the request, output checked after.
Loop a cursor API into one array
Follow nextCursor across every page and aggregate the items — no manual while-loop, cursor bookkeeping, or concat.