Request Schemas
Request schemas define what an operation accepts. In Typeweaver, request data lives under request and is split into four parts:
paramfor path parametersqueryfor query string valuesheaderfor request headersbodyfor the request body
Those schemas drive both generated request types and generated request validators.
The request shape
request: {
param?: z.object(...),
query?: z.object(...),
header?: z.object(...),
body?: z.object(...),
}
Only include the parts an operation actually uses.
param: path parameters
Path parameters use :paramName syntax in the path and must match the keys in request.param.
const GetTodoDefinition = defineOperation({
operationId: "GetTodo",
summary: "Get todo",
method: HttpMethod.GET,
path: "/todos/:todoId",
request: {
param: z.object({
todoId: z.string(),
}),
},
responses: [/* ... */],
});
If the path says :todoId, the schema must use todoId too.
query: filters and paging
query is a good fit for optional filters, search terms, and pagination on read operations.
const ListTodosDefinition = defineOperation({
operationId: "ListTodos",
summary: "List todos",
method: HttpMethod.GET,
path: "/todos",
request: {
query: z.object({
status: z.enum(["open", "done"]).optional(),
page: z.coerce.number().int().positive().optional(),
}),
},
responses: [/* ... */],
});
For most GET endpoints, param and query are the main request parts.
header: request metadata
Use header when the contract requires specific headers.
const GetTodoDefinition = defineOperation({
operationId: "GetTodo",
summary: "Get todo",
method: HttpMethod.GET,
path: "/todos/:todoId",
request: {
param: z.object({
todoId: z.string(),
}),
header: z.object({
authorization: z.string(),
}),
},
responses: [/* ... */],
});
body: create and update input
body is usually where POST, PUT, and PATCH operations put their main input.
const CreateTodoDefinition = defineOperation({
operationId: "CreateTodo",
summary: "Create todo",
method: HttpMethod.POST,
path: "/todos",
request: {
body: z.object({
title: z.string().min(1),
description: z.string().optional(),
}),
},
responses: [/* ... */],
});
As a rule of thumb:
- GET operations usually use
paramandquery - POST, PUT, and PATCH operations often use
body, sometimes withparam
Why this matters
Once the request schema is in the spec, Typeweaver can generate artifacts such as:
<OperationId>Request.ts<OperationId>RequestValidator.ts
That keeps your handlers, clients, and validators aligned with one source of truth.
This page stays focused on structure. For how invalid input is enforced at runtime, see Validation.