Validators

Generated validators are the runtime version of your Typeweaver request and response schemas. They check real request and response data against the contract you wrote in the spec.

What gets generated

Each operation generates:

  • <OperationId>RequestValidator
  • <OperationId>ResponseValidator

For example:

  • GetTodoRequestValidator
  • GetTodoResponseValidator

The request validator checks incoming request data. The response validator checks whether a response matches one of the operation's declared responses.

safeValidate() vs validate()

Generated validators expose two methods:

  • safeValidate() returns a result object
  • validate() returns validated data or throws on failure
const validator = new GetTodoRequestValidator();

const result = validator.safeValidate(httpRequest);

if (!result.isValid) {
  console.error(result.error);
}

const validatedRequest = validator.validate(httpRequest);

Use safeValidate() when you want to inspect failures yourself. Use validate() when validation failure should stop the current flow.

Example: request validation

import { HttpMethod } from "@rexeus/typeweaver-core";
import { GetTodoRequestValidator } from "./api/generated";

const validator = new GetTodoRequestValidator();

const result = validator.safeValidate({
  method: HttpMethod.GET,
  path: "/todos/todo_123",
  header: {
    Authorization: "Bearer token",
  },
  param: {
    todoId: "todo_123",
  },
});

if (result.isValid) {
  result.data.param.todoId;
}

Example: response validation

import { HttpStatusCode } from "@rexeus/typeweaver-core";
import { GetTodoResponseValidator } from "./api/generated";

const validator = new GetTodoResponseValidator();

const result = validator.safeValidate({
  statusCode: HttpStatusCode.OK,
  header: {
    "Content-Type": "application/json",
  },
  body: {
    id: "todo_123",
    title: "Ship docs",
    completed: false,
  },
});

if (result.isValid && result.data.type === "GetTodoSuccess") {
  result.data.body.title;
}

The throwing validate() alternative works the same way but raises on failure instead of returning a result object:

const response = validator.validate({
  statusCode: HttpStatusCode.OK,
  header: { "Content-Type": "application/json" },
  body: { id: "todo_123", title: "Ship docs", completed: false },
});

response.type; // "GetTodoSuccess"

When you touch validators directly

Many users rely on generated server integrations and never call validators by hand.

You usually touch them directly when:

  • writing tests for the contract boundary
  • validating data in custom middleware
  • building a custom transport layer around generated artifacts
  • debugging why a request or response no longer matches the spec

What validation buys you

Validation helps because it catches contract drift at runtime:

  • invalid requests are rejected before they reach handler logic
  • invalid handler responses are caught before they leave the server
  • generated clients can detect responses that do not match the declared contract

That keeps your types honest instead of relying on static typing alone.

Was this page helpful?