@st-api/zod-openapi
Fork of @anatine/zod-openapi
Converts a Zod schema to an OpenAPI SchemaObject
as defined by openapi3-ts
This fork was made because of a breaking change in the @anatine/zod-openapi@2.2.4, which introduced a incompatibility with OpenAPI Specification v3.0.
The original library is no longer compatible with OAS30, it's only compatible with OAS31.
Installation
Both openapi3-ts and zod are peer dependencies instead of dependant packages.
While zod
is necessary for operation, openapi3-ts
is for type-casting.
pnpm add openapi3-ts zod @st-api/zod-openapi
Usage
Take any Zod schema and convert it to an OpenAPI JSON object
import { generateSchema } from '@st-api/zod-openapi';
const aZodSchema = z.object({
uid: z.string().nonempty(),
firstName: z.string().min(2),
lastName: z.string().optional(),
email: z.string().email(),
phoneNumber: z.string().min(10).optional(),
})
const myOpenApiSchema = generateSchema(aZodSchema);
// ...
This will generate an OpenAPI schema for myOpenApiSchema
{
"type": "object",
"properties": {
"uid": {
"type": "string",
"minLength": 1
},
"firstName": {
"type": "string",
"minLength": 2
},
"lastName": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"phoneNumber": {
"type": "string",
"minLength": 10
}
},
"required": [
"uid",
"firstName",
"email"
]
}
Extend a Zod schema with additional OpenAPI schema via a function wrapper
import { extendApi, generateSchema } from '@st-api/zod-openapi';
const aZodExtendedSchema = extendApi(
z.object({
uid: extendApi(z.string().nonempty(), {
title: 'Unique ID',
description: 'A UUID generated by the server',
}),
firstName: z.string().min(2),
lastName: z.string().optional(),
email: z.string().email(),
phoneNumber: extendApi(z.string().min(10), {
description: 'US Phone numbers only',
example: '555-555-5555',
}),
}),
{
title: 'User',
description: 'A user schema',
}
);
const myOpenApiSchema = generateSchema(aZodExtendedSchema);
// ...
... or via extension of the Zod schema:
import { extendApi, generateSchema, extendZodWithOpenApi } from '@anatine/zod-openapi';
import {z} from 'zod';
extendZodWithOpenApi(z);
const aZodExtendedSchema =
z.object({
uid: z.string().nonempty().openapi({
title: 'Unique ID',
description: 'A UUID generated by the server',
}),
firstName: z.string().min(2),
lastName: z.string().optional(),
email: z.string().email(),
phoneNumber: z.string().min(10).openapi({
description: 'US Phone numbers only',
example: '555-555-5555',
}),
}).openapi(
{
title: 'User',
description: 'A user schema',
}
);
const myOpenApiSchema = generateSchema(aZodExtendedSchema);
// ...
This will generate an extended schema:
{
"type": "object",
"properties": {
"uid": {
"type": "string",
"minLength": 1,
"title": "Unique ID",
"description": "A UUID generated by the server"
},
"firstName": {
"type": "string",
"minLength": 2
},
"lastName": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"phoneNumber": {
"type": "string",
"minLength": 10,
"description": "US Phone numbers only",
"example": "555-555-5555"
}
},
"required": [
"uid",
"firstName",
"email",
"phoneNumber"
],
"title": "User",
"description": "A user schema"
}
Credits