Response Schemas
Response schemas define the allowed outcomes of an operation. They are the contract your generated clients consume and your generated server handlers must return.
Define responses with defineResponse
Here is a simple success response and a reusable error response for the todo example:
import { defineResponse, HttpStatusCode } from "@rexeus/typeweaver-core";
import { z } from "zod";
const todoSchema = z.object({
id: z.string(),
title: z.string(),
completed: z.boolean(),
});
export const GetTodoSuccessDefinition = defineResponse({
name: "GetTodoSuccess",
statusCode: HttpStatusCode.OK,
description: "Todo retrieved successfully",
body: todoSchema,
});
export const ValidationErrorDefinition = defineResponse({
name: "ValidationError",
statusCode: HttpStatusCode.BAD_REQUEST,
description: "Request validation failed",
body: z.object({
message: z.string(),
}),
});
export const TodoNotFoundErrorDefinition = defineResponse({
name: "TodoNotFoundError",
statusCode: HttpStatusCode.NOT_FOUND,
description: "Todo was not found",
body: z.object({
message: z.string(),
todoId: z.string(),
}),
});
Then attach them to the operation:
responses: [
GetTodoSuccessDefinition,
TodoNotFoundErrorDefinition,
ValidationErrorDefinition,
],
Rules worth remembering
Response names must be globally unique
Response names are not scoped to one operation. GetTodoSuccess and TodoNotFoundError must be unique across the whole spec.
That uniqueness is what lets Typeweaver generate stable types and validators without collisions.
Put the success response first
The first item in responses is the success case. Keep that ordering intentional.
Reuse shared responses
Common errors such as ValidationError can be defined once and reused across many operations. This keeps contracts consistent and reduces copy-paste drift.
Why response design matters
Clear response schemas help both sides of the contract:
- generated clients can safely discriminate on
response.type - generated server integrations know which response shapes are valid
- handlers stay honest about success and error outcomes
If your responses are vague, the generated code becomes less helpful. If your responses are explicit, the generated code does more work for you.
A note on derived responses
If you want to start from a shared base response and specialize it, Typeweaver also supports defineDerivedResponse. For a first project, plain defineResponse plus shared reusable responses is usually enough.