Automatically generate API routes with middleware and Zod from your Prisma schema.
-
This package assumes you have project initialized with Prisma, Next.JS.
-
Works best with a few dependencies to validate api-routes and keep code DRY
Using pnpm:
pnpm add -D prisma-zod-generator && pnpm add next-api-middleware zod superjson
Using yarn:
yarn add -D prisma-zod-generator && yarn add next-api-middleware zod superjson
Using npm:
npm install -D prisma-zod-generator && npm install next-api-middleware zod superjson
This repository contains an example project to play with.
git clone https://github.com/justinsgithub/prisma-generator-next && \
cd prisma-generator-next/usage && \
npm install && npm run gen && npm run dev
- Add the generator to your Prisma schema
generator zod {
provider = "prisma-zod-generator"
}
- Enable strict mode in
tsconfig
as it is required by Zod, and considered a Typescript best practice
{
"compilerOptions": {
"strict": true
}
}
- Run
npx prisma generate
If your prisma.schema looked like this...
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
content String?
published Boolean @default(false)
viewCount Int @default(0)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
likes BigInt
}
...it would generate the following files
- edit the generated files as needed
WARNING: certain files should be thought of as "read-only", as they will be regenerated every time prisma generate
is ran. Any changes to the "read-only" files would be lost, files clarify if they are okay to modify at the top.
import { PostCreateOneSchema } from './prisma/generated/schemas/createOnePost.schema';
app.post('/blog', async (req, res, next) => {
const { body } = req;
await PostCreateOneSchema.parse(body);
});
You can add options to your prisma.schema to customize generator output
Please feel free to submit an issue if you have a good idea for any new customizations or features to be added.
/// @@Gen.model(hide: true)
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
-
The output option is relative to the prisma.schema file, so the default
./generated
would output toprisma/generated
(unless you have your schema file in a custom location) -
The
outputSuffix
option is to try and protect against overwriting any files you already have in your project- example: if
output = "../"
andoutputSuffix = ""
then if you have files nameddb.ts
andmiddleware.ts
in thesrc
directory, they would be overwritten!! Along with any other files you have with the same name as the generated files.
- example: if
Option | Description | Type | Default |
---|---|---|---|
output |
Output directory for the generated files | string |
../src |
outputSuffix |
Directory the files will be output to (inside the output directory) | string |
pgen |
apiRoutePrefix |
Namespace to avoid overwriting api-routes you already have of the same name | boolean |
pgen |
prismaVarName |
Incase you use a different variable name to initialize PrismaClient | string |
prisma |
prismaFilePath |
Path to the file where you export the prisma file | string |
../src/pgen/db.ts |
useBigInt |
have Zod validate BigInt types as bigint instead of number (not recommended) | boolean |
false |
isGenerateSelect |
Enables the generation of Select related schemas and the select property | boolean |
true |
isGenerateInclude |
Enables the generation of Include related schemas and the include property | boolean |
true |
Use additional options in the schema.prisma
Important
- useBigInt defaults to false because sending a BigInt value from a web client is complicated.
- I think it is perfectly fine for Zod to just validate that it is a number because Prisma will accept it just fine.
- The BigInt type is why
superjson
is used to serialize the Prisma data before sending Response to client.
generator next {
provider = "prisma-generator-next"
output = "../src"
outputSuffix = "pgen" // ${output}/pgen/${generatedFiles}
apiRoutePrefix = "pgen" // pages/api/pgen/${modelName}
prismaFilePath = "../src/pgen/db.ts"
prismaVarName = "prisma"
useBigInt = false
isGenerateSelect = true
isGenerateInclude = true
}
-
Turn this project into a complete Next.JS app generator, including generating a front-end client for the api routes.
-
Any feedback and suggestions will be greatly appreciated.
Huge thanks to other generator projects that I was able to learn and take from.
Especially prisma-zod-generator, the code responsible for generating the Zod schemas for this project.
[typegraphql-prisma] (https://github.com/MichalLytek/typegraphql-prisma)
[prisma-trpc-generator] (https://github.com/omar-dulaimi/prisma-trpc-generator)
Also big shout out to create-prisma-generator for giving me somewhere to start from