Release candidate — 1.0.0-rc.1
StitchAPI

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

On this page