| name | fastify-routes |
| description | Guide for creating Fastify route handlers with TypeBox schemas and OpenAPI documentation. Use when adding new routes to app/src/routes/. |
Fastify Route Development
This skill provides patterns for creating Fastify routes with TypeBox validation and OpenAPI documentation.
Directory Structure
Routes are located in app/src/routes/. Each route file exports a default async function that registers routes on a Fastify instance.
Route Template
import { type FastifyPluginAsyncTypebox, Type } from "@fastify/type-provider-typebox";
import { ErrorModelSchema } from "../plugins/schema-registry.js";
const routes: FastifyPluginAsyncTypebox = async (fastify) => {
fastify.get(
"/endpoint",
{
schema: {
description: "Endpoint description for OpenAPI docs",
tags: ["tag-name"],
summary: "Short summary",
querystring: Type.Object({
param: Type.String({ description: "Query parameter" }),
}),
response: {
200: Type.Object({
status: Type.Literal("ok"),
data: Type.String({ description: "Response data" }),
}),
422: ErrorModelSchema,
500: ErrorModelSchema,
},
},
},
async (request, reply) => {
const { param } = request.query;
return { status: "ok", data: param };
},
);
};
export default routes;
OpenAPI Schema Requirements
- Always include schema: Every route handler must have a schema property
- Description and summary: Required for OpenAPI documentation
- Tags: Group related endpoints
- Response codes: Document all possible response status codes
- Error responses: Use
ErrorModelSchemafromschema-registry.jsfor error status codes (400, 404, 422, 500, 503) - TypeBox types: Use
Typefrom@fastify/type-provider-typebox - Schema discoverability: Only schemas referenced in route definitions appear in OpenAPI
components.schemas
Authentication
For protected routes, use the fastify.authenticate preHandler:
import { ErrorModelSchema } from "../plugins/schema-registry.js";
fastify.get(
"/protected",
{
preHandler: [fastify.authenticate],
schema: {
description: "Protected endpoint requiring authentication",
tags: ["protected"],
response: {
200: Type.Object({ userId: Type.String() }),
401: ErrorModelSchema,
500: ErrorModelSchema,
},
},
},
async (request) => {
return { userId: request.user.uid };
},
);
HTTP Methods
Use appropriate HTTP methods:
GET- Read operationsPOST- Create operationsPUT- Full update operationsPATCH- Partial update operationsDELETE- Delete operations
Error Handling
Use @fastify/sensible HTTP error helpers:
// Throw errors
throw fastify.httpErrors.notFound("Resource not found");
throw fastify.httpErrors.badRequest("Invalid input");
// Reply methods
reply.notFound("Resource not found");
reply.badRequest("Invalid input");
Existing Routes
health.ts- Simple liveness probe at/health(returns{ status: "healthy" })hello.ts- Greeting endpoint at/hellowith optional name parameteritems.ts- Items collection at/itemswith cursor-based pagination and category filteringroot.ts- Root endpoint at/schemas.ts- Schema discovery at/schemas/:schemaId
Testing Requirements
Each route must have a corresponding test file in app/tests/unit/routes/. Test all HTTP methods, status codes, and validation errors.
Commands
cd app
npm run build # Build and verify TypeScript compilation
npm run check # Run Biome linter and formatter
npm run test # Run all tests
Boundaries
- Do not create routes without TypeBox schemas
- Do not skip OpenAPI documentation (description, tags, summary)
- Always add corresponding unit tests for new routes