fastify-zod-openapi
fastify-zod-openapi copied to clipboard
Fastify plugin for zod-openapi
fastify-zod-openapi
Fastify type provider, validation, serialization and @fastify/swagger support for zod-openapi.
Install
Install via npm, pnpm or pnpm:
npm install zod zod-openapi fastify-zod-openapi
## or
pnpm add zod zod-openapi fastify-zod-openapi
## or
pnpm install zod-openapi fastify-zod-openapi
Usage
import 'zod-openapi/extend';
import fastify from 'fastify';
import {
type FastifyZodOpenApiSchema,
type FastifyZodOpenApiTypeProvider,
serializerCompiler,
validatorCompiler,
} from 'fastify-zod-openapi';
import { z } from 'zod';
const app = fastify();
app.setValidatorCompiler(validatorCompiler);
app.setSerializerCompiler(serializerCompiler);
app.withTypeProvider<FastifyZodOpenApiTypeProvider>().route({
method: 'POST',
url: '/:jobId',
schema: {
body: z.object({
jobId: z.string().openapi({
description: 'Job ID',
example: '60002023',
}),
}),
response: {
201: z.object({
jobId: z.string().openapi({
description: 'Job ID',
example: '60002023',
}),
}),
},
} satisfies FastifyZodOpenApiSchema,
handler: async (req, res) => {
await res.send({ jobId: req.body.jobId });
},
});
await app.ready();
await app.listen({ port: 5000 });
Usage with plugins
import 'zod-openapi/extend';
import { FastifyPluginAsyncZodOpenApi } from 'fastify-zod-openapi';
import { z } from 'zod';
const plugin: FastifyPluginAsyncZodOpenApi = async (fastify, _opts) => {
fastify.route({
method: 'POST',
url: '/',
// Define your schema
schema: {
body: z.object({
jobId: z.string().openapi({
description: 'Job ID',
example: '60002023',
}),
}),
response: {
201: z.object({
jobId: z.string().openapi({
description: 'Job ID',
example: '60002023',
}),
}),
},
} satisfies FastifyZodOpenApiSchema,
handler: async (req, res) => {
await res.send({ jobId: req.body.jobId });
},
});
};
app.register(plugin);
Usage with @fastify/swagger
import 'zod-openapi/extend';
import fastifySwagger from '@fastify/swagger';
import fastifySwaggerUI from '@fastify/swagger-ui';
import fastify from 'fastify';
import {
type FastifyZodOpenApiSchema,
type FastifyZodOpenApiTypeProvider,
fastifyZodOpenApiPlugin,
fastifyZodOpenApiTransform,
fastifyZodOpenApiTransformObject,
serializerCompiler,
validatorCompiler,
} from 'fastify-zod-openapi';
import { z } from 'zod';
import { type ZodOpenApiVersion } from 'zod-openapi';
const app = fastify();
app.setValidatorCompiler(validatorCompiler);
app.setSerializerCompiler(serializerCompiler);
const openapi: ZodOpenApiVersion = '3.0.3'; // If this is not specified, it will default to 3.1.0
await app.register(fastifyZodOpenApiPlugin, { openapi });
await app.register(fastifySwagger, {
openapi: {
info: {
title: 'hello world',
version: '1.0.0',
},
openapi,
},
transform: fastifyZodOpenApiTransform,
transformObject: fastifyZodOpenApiTransformObject,
});
await app.register(fastifySwaggerUI, {
routePrefix: '/documentation',
});
app.withTypeProvider<FastifyZodOpenApiTypeProvider>().route({
method: 'POST',
url: '/',
schema: {
body: z.string().openapi({
description: 'Job ID',
example: '60002023',
}),
response: {
201: {
content: {
'application/json': {
schema: z.object({
jobId: z.string().openapi({
description: 'Job ID',
example: '60002023',
}),
}),
},
},
},
},
} satisfies FastifyZodOpenApiSchema,
handler: async (_req, res) =>
res.send({
jobId: '60002023',
}),
});
await app.ready();
await app.listen({ port: 5000 });
Declaring Components
To declare components follow the documentation as declared here.
If you wish to declare the components manually you will need to do so via the plugin's options.
await app.register(fastifyZodOpenApiPlugin, {
openapi,
components: { schema: mySchema },
});
Please note: the responses, parameters components do not appear to be supported by the @fastify/swagger library.
Credits
fastify-type-provider-zod: Big kudos to this library for lighting the way with how to create type providers, validators and serializers. fastify-zod-openapi is just an extension to this library whilst adding support for the functionality of zod-openapi.
Development
Prerequisites
- Node.js LTS
- pnpm
pnpm install
pnpm build
Test
pnpm test
Lint
# Fix issues
pnpm format
# Check for issues
pnpm lint
Release
To release a new version
- Create a new GitHub Release
- Select
🏷️ Choose a tag, enter a version number. eg.v1.2.0and click+ Create new tag: vX.X.X on publish. - Click the
Generate release notesbutton and adjust the description. - Tick the
Set as the latest releasebox and clickPublish release. This will trigger theReleaseworkflow. - Check the
Pull Requeststab for a PR labelledRelease vX.X.X. - Click
Merge Pull Requeston that Pull Request to update main with the new package version.
To release a new beta version
- Create a new GitHub Release
- Select
🏷️ Choose a tag, enter a version number with a-beta.Xsuffix eg.v1.2.0-beta.1and click+ Create new tag: vX.X.X-beta.X on publish. - Click the
Generate release notesbutton and adjust the description. - Tick the
Set as a pre-releasebox and clickPublish release. This will trigger thePrereleaseworkflow.