@toapi/server
@toapi/server is the server half of the Toapi stack. You use it to define your API surface, implement request handlers, and turn them into a request handler that runs on any Web-standard runtime. The API definition doubles as the single source of truth for the fully-typed @toapi/client — client and server share the same types with no code generation and no build step.
Installation
Section titled “Installation”npm install @toapi/server zodzod is a peer dependency used for request and response validation.
Features
Section titled “Features”- Type-safe by construction — the shape you build with
defineApiis inferred into a single TypeScript type that the client consumes directly. No codegen, no compile step. - Auth by default — every handler defined with
defineHandlermust supply anauthorizefunction, making it nearly impossible to ship an unauthenticated endpoint by accident. - Built-in validation — request
params,query, andbody, plus theresponse, are validated with Zod. Define the schema once and get types and runtime validation together. - Automatic OpenAPI — an OpenAPI 3.1 document is generated from your route definitions. Pass
oas: { title, version }todefineApito serve it at<basePath>/__tapi/openapi.json. - Tag-based caching — responses can carry cache
tagsand attl, driving invalidation across the server, service worker, and client cache layers.
Quick start
Section titled “Quick start”Define the API surface in a shared file that both the server and the client import:
import { defineApi } from "@toapi/server";
export const api = defineApi().route("/hello", import("./routes/hello"));Implement a handler:
import { defineHandler, TResponse } from "@toapi/server";import { z } from "zod";
export const GET = defineHandler( { authorize: () => true, response: z.object({ message: z.string() }), }, async () => { return TResponse.json({ message: "Hello, world!" }); },);Turn the API into a request handler and mount it on your runtime of choice:
import { createRequestHandler } from "@toapi/server";import { api } from "./api";
export const handler = createRequestHandler(api, { basePath: "/api" });Consume it from the browser with the shared types — see @toapi/client:
// Client usageimport { createFetchClient } from "@toapi/client";import type { api } from "./api";
const client = createFetchClient<typeof api.routes>("/api");const { message } = await client.hello.get();API reference
Section titled “API reference”createRequestHandler— turn an API definition into a Web-standard request handler (the primary server entry point).defineApi— build the typed map of your routes.defineHandler— implement a single endpoint with validation and auth.createLocalClient— call your handlers in-process without an HTTP round-trip.generateOpenAPISchema— produce an OpenAPI 3.1 document from your API.streamRevalidatedTags— expose the long-polling invalidation stream.TResponse— the response helper returned from handlers.TRequest— the enhanced request passed into handlers.HttpError— throw typed HTTP error responses.PubSuband theCacheinterface — the pub/sub layer behind tag revalidation.ApiDefinition— the type produced bydefineApi.
Guides
Section titled “Guides”- Astro — mount Toapi on Astro server endpoints.
- Next.js — integrate Toapi with the App Router.
- Hono — mount Toapi routes on a Hono server.
- Bun — mount Toapi routes on a native Bun server.
Related packages
Section titled “Related packages”@toapi/client— the fully-typed fetch client.@toapi/cache— referenceCacheimplementations for server-side caching.@toapi/worker— service-worker caching and offline support.