Closed misterjame closed 1 year ago
Using Zod for nest.js config is no-brainer
This is already doable via the validate
option for @nestjs/config
Zod for DTOs leaves class-validator in the dust.
This is doable via a pipe similar to the JoiValidationPipe
, you'd just need to tweak it to use zod
instead of joi
.
The big problem of zod vs class-validator is that zod is schema and interface based and interfaces aren't reflected by the Typescript compiler during compilation, so there's no way to automatically bind the zod schema to each proper parameter like you can with class-validator.
In my opinion, it should be pretty obvious that any schema based validator is valid to use in place of the joi library, even if some modifications need to be made.
duplicate of #10960 (basically)
I like zod, but yeah. This was discussed in the past.
@nestjs/config
isn't mandatory. It has design limitations. So you can use another integration package or write your own config module insteadnestjs-zod
) that can help you outFor future reference for using Zod instead of Joi for validation NestJS environment startup check.
const localDevelopmentEnvPath = path.join(process.cwd(), 'env/api/.env.development');
ConfigModule.forRoot({
// NestJS can't validate Zod natively, we need to use a custom validation function
validate: () => {
const stage = process.env.STAGE;
if (!stage) {
console.log(
`STAGE env not defined, will try to load: ${localDevelopmentEnvPath}`
);
if (!fs.existsSync(localDevelopmentEnvPath)) {
console.log(
`File ${localDevelopmentEnvPath} does not exist!`
);
process.exit(1);
}
dotenv.config({ path: './env/api/.env.development' });
}
// apiEnvironmentValidationSchema is a Zod schema here
return apiEnvironmentValidationSchema.parse(process.env);
}
})
Slight nuance to the above solution by @renatoaraujoc is that the environment variables are passed to the validate()
method, so there is no need to use process.env
(and dotenv or similar to actually load your .env files).
So it would look more like this:
ConfigModule.forRoot({
validate: (config: Record<string, any>) => {
return myZodSchema.parse(config)
}
})
OR if you don't need to perform any other logic, you can even use the shorthand notation:
ConfigModule.forRoot({
validate: myZodSchema.parse
})
Hey @micalevisk, the nestjs-zod package has been deprecated a few days ago.
Also in that project, @kamilmysliwiec had opened an issue regarding a @nestjs/zod
package https://github.com/risen228/nestjs-zod/issues/65 which can now be considered again.
Can we re-open this issue?
Any update on this?
It would be lovely if we had a way to create DTO's from Zod schemas. It would open the door to using our schema as types for OpenAPI response or even Pipes
but without a custom validator.
Hey @kamilmysliwiec,
any insights on what you think will be the future of nest + zod would be highly appreciated! 🙃🫶
Thank you!
FYI you can easily use Zod (and others) via @nest-lab/typeschema
package.
could this issue be reopen? typeschema is nice but there's no openapi support.
@ThallesP see https://github.com/risen228/nestjs-zod/issues/65 I'm not sure about the status of that project. It's up to Kamil
We'll keep this issue closed in the moment as there are no good reason to introduce first class support for Zod in @nestjs/*
. If Kamil decides to create a new package for that integration, you guys we'll know about it, don't worry.
I've been thinking about creating an official integration package until I discovered nestjs-zod
and realized that it checks almost all the boxes (aside from things I mentioned here https://github.com/risen228/nestjs-zod/issues/65). I'm not sure what to do now since the package became deprecated; perhaps someone is willing to create a fork of that package (and maintain it down the road) as I'm not sure if adding yet another one here (under the ofc organization) makes sense
There's also @anatine/zod-nestjs
, not sure how it compares to nestjs-zod
I’m still using nestjs-zod because it really simplifies schema validation in NestJS, especially with TypeScript. However, with the deprecation, I’m concerned about potential conflicts with future NestJS versions. Honestly, if it comes to that, I might hold off on upgrading. Zod just makes everything so much easier, and I’d hate to lose that. It would be awesome to see some official support or an alternative that ensures compatibility moving forward.
FYI @risen228 transferred the repo / npm package to myself and I un-deprecated it. I plan on maintaining it going forward starting with the suggestions here: https://github.com/BenLorantfy/nestjs-zod/issues/65
Is there an existing issue that is already proposing this?
Is your feature request related to a problem? Please describe it
-DTOs using class-validator enforce validation if using validation pipe but get no type inference for use in nest.js controllers.
-Nest.JS built in ConfigService also doesn’t gain type inference for using Joi.
Describe the solution you'd like
I would like to see Zod gain first class support in Nest.js without 3rd party libraries. Using Zod for nest.js config is no-brainer. The type inference of zod will be a god send for safely accessing ConfigService type simply by using Zod validation and its infer functionality.
Zod for DTOs leaves class-validator in the dust. Zod can validate for http requests much more powerfully than class-validator. It can also infer an exact type for a DTO. You will not worry about having to mark optional DTO properties with ? In a DTO definition.
Teachability, documentation, adoption, migration strategy
docs would be changed from using joi for Config validation and would also be changed to use Zod for DTOs. It would be good too if zod was topmost indocs and therefore recommended/most supported
What is the motivation / use case for changing the behavior?
Zod is incredibly powerful tool for type validation/transformation. It also offers typescript type inference. So DTOs and ConfigService would automatically be perfectly typed just be validating them.