### Usage Example Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/validator-compiler.md An example demonstrating how to install and use the validatorCompiler with Fastify to define routes with Zod schemas for request body validation. ```APIDOC ## Usage Example ```typescript import Fastify from 'fastify' import { validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' const app = Fastify() // Install the validator compiler app.setValidatorCompiler(validatorCompiler) app.route({ method: 'POST', url: '/users', schema: { body: z.object({ name: z.string().min(1), email: z.string().email(), age: z.number().int().positive(), }), }, handler: (req, res) => { // req.body is typed as { name: string; email: string; age: number } res.send({ success: true, id: 123 }) }, }) await app.listen({ port: 3000 }) ``` ``` -------------------------------- ### Fastify Setup with Correct Installation Order Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md Ensures that Zod compilers are installed before registering plugins or defining routes. This is crucial for proper plugin initialization. ```typescript import Fastify from 'fastify' import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' const app = Fastify() // Install compilers first app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) // Then register plugins and define routes app.register(myPlugin) await app.listen() ``` -------------------------------- ### Organize Routes with Tags and Descriptions Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md This example demonstrates how to group routes using tags and provide descriptions for both listing and creating users. It configures schemas for GET /users and POST /users. ```typescript app.withTypeProvider() .route({ method: 'GET', url: '/users', schema: { tags: ['users'], description: 'List all users', response: { 200: z.array(z.object({ id: z.number(), name: z.string() })) }, }, handler: (req, res) => { res.send([]) }, }) .route({ method: 'POST', url: '/users', schema: { tags: ['users'], description: 'Create a new user', body: z.object({ name: z.string(), email: z.string().email() }), response: { 201: z.object({ id: z.number(), name: z.string(), email: z.string() }) }, }, handler: (req, res) => { res.status(201).send({ id: 1, ...req.body }) }, }) ``` -------------------------------- ### Fastify App Setup with Serializer Compiler Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/serializer-compiler.md Example of setting up a Fastify application with Zod validator and serializer compilers, and defining a typed route. ```typescript import Fastify from 'fastify' import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' import type { ZodTypeProvider } from 'fastify-type-provider-zod' const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) app.withTypeProvider().route({ method: 'GET', url: '/users/:id', schema: { params: z.object({ id: z.string(), }), response: { 200: z.object({ id: z.number(), name: z.string(), email: z.string().email(), }), }, }, handler: (req, res) => { res.send({ id: 1, name: 'John Doe', email: 'john@example.com', }) }, }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Basic Fastify Setup with Zod Compilers Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md Initializes Fastify with Zod validator and serializer compilers. This setup is required before defining routes that use Zod schemas. ```typescript import Fastify from 'fastify' import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' const app = Fastify() // Required: Install validator compiler app.setValidatorCompiler(validatorCompiler) // Required: Install serializer compiler app.setSerializerCompiler(serializerCompiler) // Now routes can use Zod schemas await app.listen({ port: 3000 }) ``` -------------------------------- ### Complete Fastify Application with Zod Type Provider Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/zod-type-provider.md A full example demonstrating Fastify setup with Zod for request/response validation and serialization, including user creation and retrieval routes. ```typescript import Fastify from 'fastify' import type { ZodTypeProvider } from 'fastify-type-provider-zod' import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' interface User { id: number name: string email: string role: 'user' | 'admin' } const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) const UserSchema = z.object({ id: z.number(), name: z.string().min(1), email: z.string().email(), role: z.enum(['user', 'admin']), }) const ErrorSchema = z.object({ error: z.string(), message: z.string(), }) app.withTypeProvider() // Create user .route({ method: 'POST', url: '/users', schema: { body: UserSchema.omit({ id: true }), response: { 201: UserSchema, 400: ErrorSchema, }, }, handler: async (req, res) => { // req.body automatically typed const newUser: User = { id: Math.random(), ...req.body, } res.status(201).send(newUser) }, }) // Get user .route({ method: 'GET', url: '/users/:id', schema: { params: z.object({ id: z.string().transform(Number) }), response: { 200: UserSchema, 404: ErrorSchema, }, }, handler: async (req, res) => { const user = findUser(req.params.id) if (!user) { return res.status(404).send({ error: 'NOT_FOUND', message: 'User not found', }) } res.send(user) }, }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Basic Swagger Setup Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md Sets up Fastify with Swagger and Swagger UI, configuring schema transformation using jsonSchemaTransform from fastify-type-provider-zod. ```typescript import Fastify from 'fastify' import fastifySwagger from '@fastify/swagger' import fastifySwaggerUI from '@fastify/swagger-ui' import { jsonSchemaTransform, serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) app.register(fastifySwagger, { openapi: { info: { title: 'My API', version: '1.0.0', }, servers: [{ url: 'http://localhost:3000' }], }, transform: jsonSchemaTransform, }) app.register(fastifySwaggerUI, { routePrefix: '/docs', }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Usage Example: Setting up Fastify with validatorCompiler Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/validator-compiler.md Demonstrates how to set up a Fastify application with the validatorCompiler and define a route with Zod-based schema validation for the request body. ```typescript import Fastify from 'fastify' import { validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' const app = Fastify() // Install the validator compiler app.setValidatorCompiler(validatorCompiler) app.route({ method: 'POST', url: '/users', schema: { body: z.object({ name: z.string().min(1), email: z.string().email(), age: z.number().int().positive(), }), }, handler: (req, res) => { // req.body is typed as { name: string; email: string; age: number } res.send({ success: true, id: 123 }) }, }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Basic Setup with Fastify Swagger Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/json-schema-transform.md Demonstrates how to integrate jsonSchemaTransform with Fastify, fastify-swagger, and fastify-swagger-ui to enable Zod schema-based API documentation. ```typescript import Fastify from 'fastify' import fastifySwagger from '@fastify/swagger' import fastifySwaggerUI from '@fastify/swagger-ui' import { jsonSchemaTransform, serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' import type { ZodTypeProvider } from 'fastify-type-provider-zod' const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) app.register(fastifySwagger, { openapi: { info: { title: 'My API', version: '1.0.0', }, servers: [{ url: 'http://localhost:3000' }], }, transform: jsonSchemaTransform, }) app.register(fastifySwaggerUI, { routePrefix: '/api/docs', }) app.after(() => { app.withTypeProvider().route({ method: 'POST', url: '/users', schema: { body: z.object({ name: z.string().describe('User full name'), email: z.string().email().describe('User email address'), }), response: { 201: z.object({ id: z.number(), name: z.string(), email: z.string(), createdAt: z.string().datetime(), }), 400: z.object({ error: z.string(), }), }, }, handler: (req, res) => { // Handler implementation }, }) }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Production-Ready Fastify Setup with Zod Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md This snippet shows a production-ready setup for Fastify using Zod for type validation and serialization. It includes custom serialization to hide sensitive fields and registers Swagger with schema transformations. ```typescript import Fastify from 'fastify' import fastifySwagger from '@fastify/swagger' import fastifySwaggerUI from '@fastify/swagger-ui' import { createJsonSchemaTransform, createJsonSchemaTransformObject, createSerializerCompiler, validatorCompiler, } from 'fastify-type-provider-zod' import { z } from 'zod/v4' const app = Fastify({ logger: true, }) // Install compilers with custom serialization const serializer = createSerializerCompiler({ replacer: (key, value) => { // Hide sensitive fields if (key === 'password' || key === 'apiKey') { return undefined } return value }, }) app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializer) // Define reusable schemas const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), role: z.enum(['user', 'admin']), createdAt: z.string().datetime(), }) const ErrorSchema = z.object({ error: z.string(), message: z.string(), code: z.string().optional(), }) // Register schemas z.globalRegistry.add(UserSchema, { id: 'User' }) z.globalRegistry.add(ErrorSchema, { id: 'Error' }) // Configure transforms const transform = createJsonSchemaTransform({ skipList: [ '/health', '/internal/*', '/documentation/*', ], schemaRegistry: z.globalRegistry, }) const transformObject = createJsonSchemaTransformObject({ schemaRegistry: z.globalRegistry, }) // Register Swagger app.register(fastifySwagger, { openapi: { openapi: '3.1.0', info: { title: 'Production API', version: '1.0.0', description: 'API with Zod validation', }, servers: [ { url: 'https://api.example.com', description: 'Production' }, { url: 'http://localhost:3000', description: 'Local' }, ], }, transform, transformObject, }) app.register(fastifySwaggerUI, { routePrefix: '/api/docs', }) // Error handler app.setErrorHandler((err, req, reply) => { if (err instanceof FastifyError && 'validation' in err) { return reply.code(400).send({ error: 'Validation Error', details: err.validation, }) } reply.code(err.statusCode || 500).send({ error: err.message || 'Internal Server Error', }) }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Request Body Example Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Defines a POST route to create a new user. It includes validation for name, email, an optional age, and a role with a default value. ```APIDOC ## POST /users ### Description Creates a new user with the provided name, email, and optional age. The user's role defaults to 'user'. ### Method POST ### Endpoint /users ### Parameters #### Request Body - **name** (string) - Required - User full name - **email** (string) - Required - User email address - **age** (number) - Optional - User age (must be an integer and at least 18) - **role** (string) - Optional - User role (defaults to 'user', can be 'user' or 'admin') ### Request Example ```json { "name": "Jane Doe", "email": "jane.doe@example.com", "age": 25, "role": "admin" } ``` ### Response #### Success Response (201) - **id** (number) - The ID of the newly created user - **name** (string) - User full name - **email** (string) - User email address - **role** (string) - User role ('user' or 'admin') #### Response Example ```json { "id": 1, "name": "Jane Doe", "email": "jane.doe@example.com", "role": "admin" } ``` ``` -------------------------------- ### Fastify with Swagger and Zod Integration Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/README.md This snippet shows the complete setup for integrating Fastify Type Provider Zod with @fastify/swagger. It includes registering plugins, defining a Zod schema, and creating a typed route. Ensure you have the necessary dependencies installed. ```typescript import fastify from 'fastify'; import fastifySwagger from '@fastify/swagger'; import fastifySwaggerUI from '@fastify/swagger-ui'; import { z } from 'zod/v4'; import type { ZodTypeProvider } from 'fastify-type-provider-zod'; import { jsonSchemaTransform, createJsonSchemaTransform, serializerCompiler, validatorCompiler, } from 'fastify-type-provider-zod'; const app = fastify(); app.setValidatorCompiler(validatorCompiler); app.setSerializerCompiler(serializerCompiler); app.register(fastifySwagger, { openapi: { info: { title: 'SampleApi', description: 'Sample backend service', version: '1.0.0', }, servers: [], }, transform: jsonSchemaTransform, // You can also create transform with custom skiplist of endpoints that should not be included in the specification: // // transform: createJsonSchemaTransform({ // skipList: [ '/documentation/static/*' ] // }) }); app.register(fastifySwaggerUI, { routePrefix: '/documentation', }); const LOGIN_SCHEMA = z.object({ username: z.string().max(32).describe('Some description for username'), password: z.string().max(32), }); app.after(() => { app.withTypeProvider().route({ method: 'POST', url: '/login', schema: { body: LOGIN_SCHEMA }, handler: (req, res) => { res.send('ok'); }, }); }); async function run() { await app.ready(); await app.listen({ port: 4949, }); console.log(`Documentation running at http://localhost:4949/documentation`); } run(); ``` -------------------------------- ### Example Validation Failures and Success Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/errors.md Illustrates various scenarios of request validation for the '/users' route, showing examples of invalid requests (missing fields, invalid data types, rule violations) and a valid request. ```http // ❌ Validation fails - missing required field 'name' POST /users { "email": "john@example.com", "age": 25 } // → 400 Bad Request, validation error for 'name' // ❌ Validation fails - invalid email POST /users { "name": "John", "email": "invalid", "age": 25 } // → 400 Bad Request, validation error for 'email' // ❌ Validation fails - age < 18 POST /users { "name": "John", "email": "john@example.com", "age": 16 } // → 400 Bad Request, validation error for 'age' // ✅ Valid request POST /users { "name": "John", "email": "john@example.com", "age": 25 } // → 201 Created ``` -------------------------------- ### Basic Usage with Zod Schemas Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/README.md Demonstrates how to set up Fastify with Zod for request validation and response serialization. Ensure Zod v4 is installed for this version. ```typescript import type { ZodTypeProvider } from 'fastify-type-provider-zod'; import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod'; import { z } from 'zod/v4'; const app = Fastify(); // Add schema validator and serializer app.setValidatorCompiler(validatorCompiler); app.setSerializerCompiler(serializerCompiler); app.withTypeProvider().route({ method: 'GET', url: '/', // Define your schema schema: { querystring: z.object({ name: z.string().min(4), }), response: { 200: z.string(), }, }, handler: (req, res) => { res.send(req.query.name); }, }); app.listen({ port: 4949 }); ``` -------------------------------- ### Headers Example Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Defines a DELETE route to remove a resource. It requires an 'authorization' header for authentication and optionally accepts an 'x-api-version' header. ```APIDOC ## DELETE /resources/:id ### Description Deletes a resource identified by its ID. Requires an authorization token in the headers. ### Method DELETE ### Endpoint /resources/:id ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the resource to delete #### Headers - **authorization** (string) - Required - Bearer token for authentication - **x-api-version** (string) - Optional - The API version ### Response #### Success Response (204) No content is returned on successful deletion. ``` -------------------------------- ### Define a Typed Route with Zod Schema Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/README.md Define a GET route with parameters and response schema using Zod. This example demonstrates how to specify types for route parameters and responses, including transforming input. ```typescript import type { ZodTypeProvider } from 'fastify-type-provider-zod' import { z } from 'zod/v4' app.withTypeProvider().route({ method: 'GET', url: '/users/:id', schema: { params: z.object({ id: z.string().transform(Number) }), response: { 200: z.object({ id: z.number(), name: z.string() }) }, }, handler: (req, res) => { res.send({ id: req.params.id, name: 'User' }) }, }) ``` -------------------------------- ### Query Parameters Example Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Defines a route to fetch users with optional query parameters for pagination (page, limit), sorting, and searching. Default values are provided for page and limit. ```APIDOC ## GET /users ### Description Fetches a list of users with options for pagination, sorting, and searching. Default pagination is set to page 1 with 10 items per page. ### Method GET ### Endpoint /users ### Parameters #### Query Parameters - **page** (number) - Optional - The page number for pagination (defaults to 1) - **limit** (number) - Optional - The number of items per page (defaults to 10) - **sort** (string) - Optional - The field to sort by (e.g., 'name', 'email', 'created') - **search** (string) - Optional - A search term to filter users ### Response #### Success Response (200) - **users** (array) - An array of user objects, each with 'id' and 'name' - **total** (number) - The total number of users available - **page** (number) - The current page number #### Response Example ```json { "users": [ { "id": 1, "name": "John Doe" } ], "total": 1, "page": 1 } ``` ``` -------------------------------- ### Development Fastify Setup with Detailed Logging Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md This snippet configures Fastify for development with detailed logging using 'pino-pretty'. It also includes a custom serializer that logs each serialized field, aiding in debugging. ```typescript import Fastify from 'fastify' import { jsonSchemaTransform, serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' const app = Fastify({ logger: { level: 'debug', transport: { target: 'pino-pretty', }, }, }) app.setValidatorCompiler(validatorCompiler) // In development, log detailed serialization data const devSerializer = createSerializerCompiler({ replacer: (key, value) => { console.log(`Serializing: ${key} = ${typeof value}`) return value }, }) app.setSerializerCompiler(devSerializer) app.register(fastifySwagger, { openapi: { info: { title: 'Dev API', version: '0.0.1' }, }, transform: jsonSchemaTransform, }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Set Serializer Compiler Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/README.md Install the serializer compiler using `app.setSerializerCompiler(serializerCompiler)` to validate and serialize outgoing response data. ```typescript app.setSerializerCompiler(serializerCompiler) ``` -------------------------------- ### Type Inference Example Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/zod-type-provider.md Demonstrates how to define a route with Zod schemas for parameters, query string, body, headers, and responses, and shows the automatically inferred types for the request handler. ```APIDOC ## GET /users/:id ### Description This endpoint demonstrates type inference for request schemas including parameters, query string, body, headers, and responses using Zod. ### Method GET ### Endpoint /users/:id ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user. #### Query Parameters - **include** (enum: 'profile', 'posts') - Optional - Specifies additional data to include. #### Request Body - **name** (string) - Required - The name of the user. #### Headers - **authorization** (string) - Required - The authorization token. ### Request Example ```json { "name": "John Doe" } ``` ### Response #### Success Response (200) - **id** (number) - The user's ID. - **name** (string) - The user's name. #### Response Example ```json { "id": 1, "name": "John Doe" } ``` #### Error Response (404) - **error** (string) - Description of the error. #### Response Example ```json { "error": "User not found" } ``` ``` -------------------------------- ### Multi-Version API Setup with Fastify and Zod Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md This snippet demonstrates setting up a Fastify application to serve multiple API versions (V1 and V2) independently. Each version has its own Swagger configuration and documentation route, with distinct skiplists for schema transformations. ```typescript import Fastify from 'fastify' import { createJsonSchemaTransform, createSerializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(createSerializerCompiler()) // V1 API with skiplist const v1Transform = createJsonSchemaTransform({ skipList: ['/documentation/*', '/v2/*'], }) // V2 API with different skiplist const v2Transform = createJsonSchemaTransform({ skipList: ['/documentation/*', '/v1/*'], }) // Register V1 Swagger separately app.register(async (app) => { app.register(fastifySwagger, { openapi: { info: { title: 'API V1', version: '1.0.0' }, servers: [{ url: '/v1' }], }, transform: v1Transform, }) app.register(fastifySwaggerUI, { routePrefix: '/v1/docs', }) }) // Register V2 Swagger separately app.register(async (app) => { app.register(fastifySwagger, { openapi: { info: { title: 'API V2', version: '2.0.0' }, servers: [{ url: '/v2' }], }, transform: v2Transform, }) app.register(fastifySwaggerUI, { routePrefix: '/v2/docs', }) }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Define JSON and Custom Format Responses Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Configure a route to respond with different schemas based on the `Accept` header. This example shows how to provide a standard JSON response and a custom `application/vnd.custom+json` format. ```typescript app.withTypeProvider().route({ method: 'GET', url: '/data/:id', schema: { params: z.object({ id: z.string() }), response: { 200: { description: 'Data in requested format', content: { // JSON response 'application/json': { schema: z.object({ id: z.number(), name: z.string(), values: z.array(z.number()), }), }, // Custom format 'application/vnd.custom+json': { schema: z.object({ metadata: z.object({ version: z.string() }), data: z.array(z.object({ id: z.number(), name: z.string() })) }), }, }, }, }, }, handler: (req, res) => { const data = { id: 1, name: 'Item', values: [1, 2, 3] } // Client sends Accept header to request format if (req.headers.accept?.includes('application/vnd.custom+json')) { res.header('Content-Type', 'application/vnd.custom+json') res.send({ metadata: { version: '1.0' }, data: [data] }) } else { res.header('Content-Type', 'application/json') res.send(data) } }, }) ``` -------------------------------- ### Custom Schema Registry Setup Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/configuration.md Registers reusable schemas with a custom ID and uses the schema registry for OpenAPI component generation with createJsonSchemaTransform and createJsonSchemaTransformObject. ```typescript import { createJsonSchemaTransform, createJsonSchemaTransformObject } from 'fastify-type-provider-zod' import { z } from 'zod/v4' // Define reusable schemas const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), }) const ErrorSchema = z.object({ error: z.string(), message: z.string(), }) // Register with ID z.globalRegistry.add(UserSchema, { id: 'User' }) z.globalRegistry.add(ErrorSchema, { id: 'Error' }) // Create transforms that use the registry const transform = createJsonSchemaTransform({ schemaRegistry: z.globalRegistry, }) const transformObject = createJsonSchemaTransformObject({ schemaRegistry: z.globalRegistry, }) app.register(fastifySwagger, { openapi: { /* ... */ }, transform, transformObject, }) ``` -------------------------------- ### Setup OpenAPI Documentation with Zod Schema Transformation Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/README.md Register Fastify plugins for Swagger and Swagger UI, configuring them to use Zod for schema transformation. This enables automatic generation of OpenAPI documentation from your Zod schemas. ```typescript import fastifySwagger from '@fastify/swagger' import fastifySwaggerUI from '@fastify/swagger-ui' import { jsonSchemaTransform, jsonSchemaTransformObject } from 'fastify-type-provider-zod' app.register(fastifySwagger, { openapi: { info: { title: 'API', version: '1.0.0' }, }, transform: jsonSchemaTransform, transformObject: jsonSchemaTransformObject, }) app.register(fastifySwaggerUI, { routePrefix: '/docs', }) ``` -------------------------------- ### JSON and XML Responses Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md This example demonstrates how to define both a standard JSON response and a custom JSON response ('application/vnd.custom+json') for the same endpoint. The server selects the response format based on the client's Accept header. ```APIDOC ## GET /data/:id ### Description Retrieves data for a specific ID, with support for both standard JSON and a custom JSON format. ### Method GET ### Endpoint /data/:id ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the data to retrieve. ### Response #### Success Response (200) - **description**: 'Data in requested format' - **content**: - **application/json**: Schema for standard JSON response. - **application/vnd.custom+json**: Schema for a custom JSON response format. ### Request Example ```json { "example": "No request body for GET" } ``` ### Response Example #### application/json ```json { "id": 1, "name": "Item", "values": [ 1, 2, 3 ] } ``` #### application/vnd.custom+json ```json { "metadata": { "version": "1.0" }, "data": [ { "id": 1, "name": "Item" } ] } ``` ``` -------------------------------- ### Set Validator Compiler Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/README.md Install the validator compiler using `app.setValidatorCompiler(validatorCompiler)` to validate request data against Zod schemas. ```typescript app.setValidatorCompiler(validatorCompiler) ``` -------------------------------- ### Route Parameters Example Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Defines a route with path parameters 'id' and 'postId'. The 'id' parameter is transformed into a number, while 'postId' remains a string. The response schema specifies a 200 OK with a user object. ```APIDOC ## GET /users/:id/posts/:postId ### Description Retrieves posts for a specific user, with path parameters for user ID and post ID. The user ID is automatically converted to a number. ### Method GET ### Endpoint /users/:id/posts/:postId ### Parameters #### Path Parameters - **id** (number) - Required - User ID (coerced to number) - **postId** (string) - Required - Post ID ### Response #### Success Response (200) - **id** (number) - User ID - **title** (string) - Post title - **userId** (number) - The ID of the user who created the post #### Response Example ```json { "id": 1, "title": "Post", "userId": 1 } ``` ``` -------------------------------- ### Create a Fastify Plugin with Zod Schema Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/README.md This snippet demonstrates how to define a Fastify route with query string and response schemas using Zod. Ensure Zod and Fastify Type Provider Zod are installed. ```typescript import { z } from 'zod/v4'; import type { FastifyPluginAsyncZod } from 'fastify-type-provider-zod'; const plugin: FastifyPluginAsyncZod = async function (fastify, _opts) { fastify.route({ method: 'GET', url: '/', // Define your schema schema: { querystring: z.object({ name: z.string().min(4), }), response: { 200: z.string(), }, }, handler: (req, res) => { res.send(req.query.name); }, }); }; ``` -------------------------------- ### Basic Custom Serializer with Date Handling Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/create-serializer-compiler.md Creates a custom serializer that transforms Date objects into a specific format before JSON serialization. This example demonstrates how to integrate it with Fastify routes and schemas. ```typescript import Fastify from 'fastify' import { createSerializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' import type { ZodTypeProvider } from 'fastify-type-provider-zod' const app = Fastify() app.setValidatorCompiler(validatorCompiler) // Create a custom serializer that handles Date objects const customSerializer = createSerializerCompiler({ replacer(key, value) { if (value instanceof Date) { return { _date: value.toISOString() } } return value }, }) app.setSerializerCompiler(customSerializer) app.withTypeProvider().route({ method: 'GET', url: '/events/:id', schema: { params: z.object({ id: z.string() }), response: { 200: z.object({ id: z.number(), name: z.string(), createdAt: z.instanceof(Date), }), }, }, handler: (req, res) => { res.send({ id: 1, name: 'Launch Event', createdAt: new Date('2024-01-15'), }) }, }) ``` -------------------------------- ### JSON Array Variants Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md This example shows how to provide different JSON array formats for an endpoint: a flat array and a paginated array. The server responds with the format specified in the client's Accept header. ```APIDOC ## GET /items ### Description Retrieves a list of items, supporting both a flat JSON array and a paginated JSON array format. ### Method GET ### Endpoint /items ### Parameters #### Path Parameters None #### Query Parameters None ### Response #### Success Response (200) - **description**: 'Items with multiple response formats' - **content**: - **application/json**: Schema for a flat JSON array of items. - **application/vnd.paginated+json**: Schema for a paginated JSON array of items. ### Request Example ```json { "example": "No request body for GET" } ``` ### Response Example #### application/json ```json [ { "id": 1, "name": "Item 1" } ] ``` #### application/vnd.paginated+json ```json { "data": [ { "id": 1, "name": "Item 1" } ], "page": 1, "total": 1 } ``` ``` -------------------------------- ### Create a Fastify Plugin with Zod Type Provider Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/README.md Define a Fastify plugin that utilizes the Zod type provider for defining typed routes. This example shows how to create a reusable plugin with its own schema definitions. ```typescript import type { FastifyPluginAsyncZod } from 'fastify-type-provider-zod' import { z } from 'zod/v4' const myPlugin: FastifyPluginAsyncZod = async (fastify) => { fastify.route({ method: 'GET', url: '/status', schema: { response: { 200: z.object({ status: z.literal('ok') }) }, }, handler: (req, res) => { res.send({ status: 'ok' }) }, }) } app.register(myPlugin) ``` -------------------------------- ### Registering Zod Schemas with IDs for OpenAPI Refs Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/README.md This example demonstrates how to register Zod schemas with a global registry using unique IDs. These IDs are then used by fastify-swagger to create references within the OpenAPI document. ```typescript import fastifySwagger from '@fastify/swagger'; import fastifySwaggerUI from '@fastify/swagger-ui'; import fastify from 'fastify'; import { z } from 'zod/v4'; import type { ZodTypeProvider } from 'fastify-type-provider-zod'; import { jsonSchemaTransformObject, jsonSchemaTransform, serializerCompiler, validatorCompiler, } from 'fastify-type-provider-zod'; const USER_SCHEMA = z.object({ id: z.number().int().positive(), name: z.string().describe('The name of the user'), }); z.globalRegistry.add(USER_SCHEMA, { id: 'User' }); const app = fastify(); app.setValidatorCompiler(validatorCompiler); app.setSerializerCompiler(serializerCompiler); app.register(fastifySwagger, { openapi: { info: { title: 'SampleApi', description: 'Sample backend service', version: '1.0.0', }, servers: [], }, transform: jsonSchemaTransform, transformObject: jsonSchemaTransformObject, }); app.register(fastifySwaggerUI, { routePrefix: '/documentation', }); app.after(() => { app.withTypeProvider().route({ method: 'GET', url: '/users', schema: { response: { 200: USER_SCHEMA.array(), }, }, handler: (req, res) => { res.send([]); }, }); }); async function run() { await app.ready(); await app.listen({ port: 4949, }); console.log(`Documentation running at http://localhost:4949/documentation`); } run(); ``` -------------------------------- ### Fastify Route with Zod Schemas Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/api-reference/zod-type-provider.md Example demonstrating how to use ZodTypeProvider with Fastify. It sets up validator and serializer compilers and defines a POST route with Zod-based schemas for the request body and response. The handler function benefits from automatically inferred types for `req.body` and `res.send`. ```typescript import Fastify from 'fastify' import type { ZodTypeProvider } from 'fastify-type-provider-zod' import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' import { z } from 'zod/v4' const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) // Use withTypeProvider to enable Zod schema type inference app.withTypeProvider().route({ method: 'POST', url: '/users', schema: { body: z.object({ name: z.string(), email: z.string().email(), age: z.number().int().optional(), }), response: { 201: z.object({ id: z.number(), name: z.string(), email: z.string(), age: z.number().int().optional(), }), }, }, handler: (req, res) => { // req.body is automatically typed as: // { name: string; email: string; age?: number } // res.send() is typed to accept: // { id: number; name: string; email: string; age?: number } res.status(201).send({ id: 1, name: req.body.name, email: req.body.email, age: req.body.age, }) }, }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Fastify with Zod Type Provider Quick Start Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/README.md Sets up a Fastify server with Zod type validation for POST requests. It configures the validator and serializer compilers and defines a route with a request body schema and a response schema. ```typescript import Fastify from 'fastify' import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod' import type { ZodTypeProvider } from 'fastify-type-provider-zod' import { z } from 'zod/v4' const app = Fastify() app.setValidatorCompiler(validatorCompiler) app.setSerializerCompiler(serializerCompiler) app.withTypeProvider().route({ method: 'POST', url: '/users', schema: { body: z.object({ name: z.string(), email: z.string().email(), }), response: { 201: z.object({ id: z.number(), name: z.string(), email: z.string(), }), }, }, handler: (req, res) => { res.status(201).send({ id: 1, name: req.body.name, email: req.body.email, }) }, }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Multiple Status Codes Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Handles GET requests to '/users/:id', supporting both a successful user retrieval (200) and a not found error (404). It includes path parameters for user ID. ```APIDOC ## GET /users/:id ### Description Retrieves a user by their ID. Supports returning user details on success or a not found error. ### Method GET ### Endpoint /users/:id ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user to retrieve. ### Response #### Success Response (200) - **id** (number) - The user's ID. - **name** (string) - The user's name. - **email** (string) - The user's email address. #### Error Response (404) - **error** (string literal 'not_found') - Indicates that the user was not found. - **message** (string) - A message detailing the error. #### Response Example (Success) { "id": 1, "name": "John Doe", "email": "john.doe@example.com" } #### Response Example (Not Found) { "error": "not_found", "message": "User not found" } ``` -------------------------------- ### RESTful CRUD Collection for Users Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md This snippet shows a full implementation of CRUD operations for a user resource. It includes schema definitions for user data, error responses, and request/response validation for GET, POST, PUT, and DELETE methods on /users and /users/:id endpoints. Use this for standard resource management. ```typescript const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), createdAt: z.string().datetime(), }) const ErrorSchema = z.object({ error: z.string(), message: z.string(), }) app.withTypeProvider() // List users .route({ method: 'GET', url: '/users', schema: { tags: ['users'], querystring: z.object({ page: z.string().default('1').transform(Number), limit: z.string().default('10').transform(Number), }), response: { 200: z.object({ data: UserSchema.array(), pagination: z.object({ page: z.number(), total: z.number() }), }), }, }, handler: (req, res) => { res.send({ data: [], pagination: { page: 1, total: 0 } }) }, }) // Create user .route({ method: 'POST', url: '/users', schema: { tags: ['users'], body: UserSchema.omit({ id: true, createdAt: true }), response: { 201: UserSchema, 400: ErrorSchema }, }, handler: (req, res) => { res.status(201).send({ id: 1, ...req.body, createdAt: new Date().toISOString() }) }, }) // Get user .route({ method: 'GET', url: '/users/:id', schema: { tags: ['users'], params: z.object({ id: z.string().transform(Number) }), response: { 200: UserSchema, 404: ErrorSchema }, }, handler: (req, res) => { res.send({ id: req.params.id, name: 'User', email: 'user@example.com', createdAt: new Date().toISOString() }) }, }) // Update user .route({ method: 'PUT', url: '/users/:id', schema: { tags: ['users'], params: z.object({ id: z.string().transform(Number) }), body: UserSchema.omit({ id: true, createdAt: true }).partial(), response: { 200: UserSchema, 404: ErrorSchema }, }, handler: (req, res) => { res.send({ id: req.params.id, name: 'Updated', email: 'updated@example.com', createdAt: new Date().toISOString() }) }, }) // Delete user .route({ method: 'DELETE', url: '/users/:id', schema: { tags: ['users'], params: z.object({ id: z.string().transform(Number) }), response: { 204: z.undefined(), 404: ErrorSchema }, }, handler: (req, res) => { res.status(204).send() }, }) ``` -------------------------------- ### RESTful CRUD Collection - Get user Source: https://github.com/turkerdev/fastify-type-provider-zod/blob/main/_autodocs/endpoints.md Retrieves a specific user by their ID. ```APIDOC ## GET /users/:id ### Description Retrieves a specific user by their ID. ### Method GET ### Endpoint /users/:id ### Parameters #### Path Parameters - **id** (number) - Required - The unique identifier of the user. ### Response #### Success Response (200) - **id** (number) - The user's unique identifier. - **name** (string) - The user's name. - **email** (string) - The user's email address. - **createdAt** (string) - The date and time the user was created. #### Error Response (404) - **error** (string) - A general error code. - **message** (string) - A detailed error message. #### Response Example { "id": 1, "name": "User", "email": "user@example.com", "createdAt": "2023-10-27T10:00:00.000Z" } ```