nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.68k stars 7.63k forks source link

Zod first class support #10974

Closed misterjame closed 1 year ago

misterjame commented 1 year ago

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.

jmcdo29 commented 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.

micalevisk commented 1 year ago

duplicate of #10960 (basically)


I like zod, but yeah. This was discussed in the past.

  1. @nestjs/config isn't mandatory. It has design limitations. So you can use another integration package or write your own config module instead
  2. there are community-made packages (like nestjs-zod) that can help you out
renatoaraujoc commented 1 year ago

For 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);
    }
})
NielsCodes commented 6 months ago

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
})
hymair commented 6 months ago

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?

Armadillidiid commented 5 months ago

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.

buti1021 commented 4 months ago

Hey @kamilmysliwiec,

any insights on what you think will be the future of nest + zod would be highly appreciated! 🙃🫶

Thank you!

micalevisk commented 4 months ago

FYI you can easily use Zod (and others) via @nest-lab/typeschema package.

ThallesP commented 2 months ago

could this issue be reopen? typeschema is nice but there's no openapi support.

micalevisk commented 2 months ago

@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.

kamilmysliwiec commented 2 months ago

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

vladkrasn commented 2 months ago

There's also @anatine/zod-nestjs, not sure how it compares to nestjs-zod

yordan-kanchelov commented 2 months ago

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.

BenLorantfy commented 3 weeks ago

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