API Reference

k.routes

Define a group of routes under one tag, with full path-param and response checking.

k.routes(tag, defs) defines a group of routes under one tag. The tag must be a key of the tag set your Config carries, and TypeScript completes it.

users.ts
import { z } from 'zod';
import { k } from './k';

export const usersRoutes = k.routes('users', {
    listUsers: k
        .route({
            method: 'GET',
            path: '/users',
            query: z.object({
                page: z.number().int().min(1).default(1),
                limit: z.number().int().min(1).max(100).default(10),
            }),
            responses: {
                200: z.object({
                    users: z.array(UserSchema),
                    total: z.number(),
                }),
            },
        })
        .handler(/* ... */),
    createUser: k
        .route({
            method: 'POST',
            path: '/users',
            body: z.object({
                name: z.string().min(1),
                email: z.email(),
            }),
            responses: {
                201: UserSchema,
                400: ProblemDetailsSchema,
            },
        })
        .handler(/* ... */),
    getUser: k
        .route({
            method: 'GET',
            path: '/users/:id',
            responses: {
                200: UserSchema,
                404: ProblemDetailsSchema,
            },
        })
        .handler(/* ... */),
});

Route definition fields

FieldRequiredType
methodYes'GET' 'POST' 'PUT' 'PATCH' 'DELETE' 'HEAD' 'OPTIONS'
pathYesURL path. Use :name for path parameters
pathParamsNoZod schema for the path parameters, keyed by placeholder name
bodyNoZod schema for the request body
queryNoZod schema for the query string
headersNoZod schema for request headers
responsesYesResponse schemas keyed by status code. A schema, { body, headers?, contentType? }, or { stream, headers?, contentType? }
contentTypeNo'application/json' (default), 'multipart/form-data', 'application/x-www-form-urlencoded'
summaryNoShort description shown in OpenAPI
descriptionNoLonger description shown in OpenAPI
externalDocsNo{ url, description? }, emitted on the operation
tagsNoOpenAPI tag keys (from the tag set), resolved to titles in the spec
deprecatedNoboolean | string | { message?, date?, link? }, see Deprecations
sunsetNostring | { date, link? }, see Deprecations

Use the { body, headers?, contentType?, cache?, etag? } form of a response to declare typed response headers, a binary body, or a cache policy and entity tag. Use { stream, headers?, contentType? } to send the response piece by piece, see Streaming.

A route's security is resolved from its auth; writing it here is a type error.

Validation

pathParams keys must be exactly the :name placeholders in path. A mismatch is a type error on pathParams, and k.routes throws on it at runtime.

k.routes also throws on:

  • an empty z.object({}) as a body
  • any z.coerce schema, anywhere in the route
  • a structured path parameter (object, array, record, tuple, map, or set)
  • a stream on a 4xx or 5xx status, beside a body, or on a HEAD route
  • a stream whose schema does not fit its contentType: a text/* type takes z.string(), any other non-JSON type takes BinarySchema
  • a stream event name that is empty or contains a line break

On this page