DocTreen

defineRoute

Explicit route definition with full schema control.

For full control, wrap a handler with defineRoute. Works the same across Express, Fastify, Hono, and Koa:

const { defineRoute, s } = require('doctreen/express');
// const { defineRoute, s } = require('doctreen/fastify');
// import { defineRoute, s } from 'doctreen/hono';
// const { defineRoute, s } = require('doctreen/koa');

app.post('/users', defineRoute(
  (req, res) => {
    res.status(201).json({ id: 1, name: req.body.name });
  },
  {
    description: 'Create a new user account',
    headers: {
      Authorization:  'Bearer <token>',
      'Content-Type': 'application/json',
    },
    request: {
      body:  s.object({ name: s.string(), email: s.string(), role: s.optional(s.string()) }),
      query: null,
    },
    response: s.object({ id: s.number(), name: s.string(), email: s.string() }),
    errors: {
      409: 'Email address already in use',
      422: { description: 'Validation failed', schema: s.object({ message: s.string(), field: s.string() }) },
    },
  }
));

Schema resolution order

AdapterPriority
ExpressdefineRoute → JSDoc → runtime inference
FastifydefineRoute → Fastify native JSON Schema → JSDoc
HonodefineRoute → JSDoc
KoadefineRoute → JSDoc
NestJS@DocRoute / @Doc* decorators

Options

OptionTypeNotes
descriptionstringHuman-readable description shown in the UI
summarystringShort title for the operation
headersRecord<string, string>Request headers — example value as the map value
request.bodyZod | SchemaNodeRequest body
request.queryZod | SchemaNodeQuery parameters
responseZod | SchemaNodeSuccess response (200 / 201)
errorsRecord<number, string | { description?, schema? }>Documented error responses
validatebooleanPer-route override of adapter-level validate setting
tagsstring[]Override the path-segment default tag
securityArray<Record<string, string[]>>Per-route security override
hiddenbooleanHide from docs UI and OpenAPI
examplesRouteExamplesMulti-example bodies and responses (v1.11+)
callbacksRecord<string, CallbackDef>Per-operation OpenAPI 3.1 callbacks

With TypeScript generics

import { defineRoute, RouteSchemas } from 'doctreen/express';
import { s } from 'doctreen';

app.post('/users', defineRoute<{ name: string }, never, { id: number; name: string }>(
  (req, res) => res.status(201).json({ id: 1, name: req.body.name }),
  {
    description: 'Create a user',
    request:  { body: s.object({ name: s.string() }) },
    response: s.object({ id: s.number(), name: s.string() }),
  }
));

See TypeScript for the full type catalogue.

On this page