> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://cla-demo.postmansolutions.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://cla-demo.postmansolutions.com/_mcp/server.

# Zod OpenAPI

Zod-OpenAPI Integration Issues

We attempted to integrate **Zod** with **OpenAPI** using the **`zod-openapi`** library to automatically generate OpenAPI documentation while maintaining type-safe runtime validation. The integration aimed to streamline the development process by using Zod for both validation and documentation generation.

### Challenges Encountered

1. **Issue with `$ref` and `required` Fields**:
   * When using **Zod** schemas, the generated **JSON schema** often contained `$ref` references to the `definitions` object, which Fastify could not resolve, resulting in errors such as:
     * **`can't resolve reference #/definitions/UserSchema`**.

     * **`data/required must be array`** — Fastify requires `required` to be an **array** of field names (e.g., `['id', 'name', 'email']`), but `zod-openapi` didn’t automatically format the `required` field as an array.

     * here is the screenshot of the error: ![image.png](/_fern-img/7cb283aeb22c94a22931009964903feafef1c0355f56fb03cfce0ace090b79b7.webp)
2. **JSON Schema Generation**:
   * The **Zod-to-JSON Schema** conversion using **`zod-openapi`** was producing an **incorrect schema format** that Fastify couldn’t interpret. Specifically, the `properties` field was not properly set, and `$ref` was incorrectly being used in the schema, which Fastify doesn’t support.

Converting this zod schema object by using `zodToJsonSchema(UserSchema, 'UserSchema');`

```
const UserSchema = z.object({
  id: z.uuid(),
  name: z.string().min(1),
  email: z.email(),
}).strict();
```

will result to:

```
{"$ref":"#/definitions/UserSchema","definitions":{"UserSchema":{"type":"string"}},"$schema":"http://json-schema.org/draft-07/schema#"}
```

3. **OpenAPI Documentation Integration**:
   * While **`zod-openapi`** generated the **OpenAPI documentation** correctly in most cases, Fastify's **Swagger plugin** required the schema to be in a **specific format**, causing issues when trying to directly integrate **Zod schemas** into Fastify's schema validation system.

\##Sample proof-of-concept Code

```

import { z } from 'zod';
import { extendZodWithOpenApi } from '@hono/zod-openapi';

extendZodWithOpenApi(z);

const UserSchema = z.object({
  id: z.string().uuid({ message: 'Invalid UUID format' }),
  name: z.string().min(1, { message: 'Name is required' }),
  email: z.string().email({ message: 'Invalid email address' }),
});


const CreateUserResponse = UserSchema.openapi({
  description: 'Response after creating a user',
});



export const routes = async (frameworkServer: FastifyInstance) => {

  frameworkServer.post('/demo/user', {
    schema: {
      body: UserSchema, // Zod schema for the request body
      response: {
        201: CreateUserResponse, 
      },
    },
    handler: async (request, reply) => {
      const { id, name, email } = UserSchema.parse(request.body); 
      reply.status(201).send({ id, name, email });
    },
  });
  
  }
```

**zod-openapi** is not specifically designed for Fastify, it is primarily intended for OpenAPI documentation generation from Zod schemas.