Validation

Validation is what turns a Typeweaver contract into a runtime boundary.

Because request and response schemas live in the spec, Typeweaver can generate validators that check incoming requests and outgoing responses against the contract instead of relying on convention.

What Typeweaver validates

In normal day-to-day use, there are three practical validation points:

  1. incoming requests against the operation's param, query, header, and body schemas
  2. outgoing responses returned by generated server integrations
  3. client-side response parsing when a generated client receives an HTTP response

That is why generated output includes files such as:

  • <OperationId>RequestValidator.ts
  • <OperationId>ResponseValidator.ts

By default, generated output includes the request and response types plus the validators derived from your spec, so these files are available without extra plugin selection.

This page focuses on where validation happens in the overall workflow. For the concrete generated validator classes and methods, see Validators.

Why it matters in practice

Without validation, a handler can quietly accept the wrong input or return a shape the client does not actually understand.

With validation:

  • bad requests are rejected before they reach your handler logic
  • handlers are kept honest about the responses they return
  • generated clients can detect responses that do not match the contract

That gives you faster feedback while building and fewer surprises at runtime.

Request validation happens before handlers

When you use the generated Hono or server integration, request validation runs before your handler is called.

That means your handler receives already-validated request data instead of raw transport input.

Response validation happens on generated server paths

Both server integration paths validate the response returned by your handler against the operation's declared responses.

If a handler returns a response shape that does not match the contract, Typeweaver treats that as a server-side contract problem instead of silently shipping the wrong payload.

safeValidate() and validate()

Generated validators give you two practical modes:

  • safeValidate() returns a result object you can inspect
  • validate() throws if validation fails
const validator = new GetTodoRequestValidator();

const result = validator.safeValidate(httpRequest);

if (!result.isValid) {
  return;
}

const validatedRequest = validator.validate(httpRequest);

Use safeValidate() when you want to branch manually. Use validate() when you want the calling framework or integration path to handle validation failures.

When you typically care

Most users do not need to call validators directly on day one.

You usually care about them when:

  • you want to understand what the generated Hono or server path is doing
  • you are writing custom middleware around generated handlers
  • you want manual validation in a custom boundary

If you are using generated integrations directly, validation is already doing useful work for you.

Was this page helpful?