Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

accept ZOD validator #4414

Closed
radoslavirha opened this issue Jan 14, 2023 · 8 comments
Closed

accept ZOD validator #4414

radoslavirha opened this issue Jan 14, 2023 · 8 comments
Labels
support Questions, discussions, and general support

Comments

@radoslavirha
Copy link
Contributor

Support plan

  • is this issue currently blocking your project? (yes/no): no
  • is this issue affecting a production system? (yes/no): no

Context

  • node version: 16.16.0
  • module version: 21.1.0
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): hapi application
  • any other relevant information:

How can we help?

Basically I would like to replace Joi with ZOD (better with typescript, type inference). I can set my own validation on each route, validate payload/params/query and return error/pass. But Hapi always adds own validation object in returned error, I would say it expects Joi errror and is written to parse it. It would be nice to accept ZOD on route validation.

Just set?:
server.validator(z);

and use

{
  method: 'POST',
  path: `/validate`,
  handler: (req, h) => h.response().code(200),
  options: {
    validate: {
      payload: z.object({
        a: z.string(),
        b: z.string()
      })
    }
  }
}

instead of:

{
  method: 'POST',
  path: `/validate`,
  handler: (req, h) => h.response().code(200),
  options: {
    validate: {
      payload: Joi.object({
        a: Joi.string().required(),
        b: Joi.string().required()
      })
    }
  }
}

I can create validators and infere types in separate files, and use it as needed.

Thanks

@radoslavirha radoslavirha added the support Questions, discussions, and general support label Jan 14, 2023
@devinivy
Copy link
Member

devinivy commented Jan 15, 2023

It should just be a handful of lines of code to get basic zod support working. Here's a working example: https://runkit.com/devinivy/63c4627a352d980008baa41b. The core idea is this:

const zodValidator = {
    compile: (schema) => ({
        validate: (val) => schema.parse(val)
    })
};

server.validator(zodValidator);

@radoslavirha
Copy link
Contributor Author

Is it something that the hapi team considers to be the right way?

@cjihrig
Copy link
Contributor

cjihrig commented Jan 25, 2023

@Radik24, @devinivy is part of the hapi team 😄

@radoslavirha
Copy link
Contributor Author

I know, I just want to know if it's kind of hack or it could be implemented natively in future :)

@cjihrig
Copy link
Contributor

cjihrig commented Jan 25, 2023

I'm not a zod user, but the solution looks legit to me. I'll let Devin comment further.

@devinivy
Copy link
Member

Yep, you should be good to go! Any change to this validator interface would be considered a breaking change to hapi, i.e. it's considered part of our API. If anyone is interested in calling this out more explicitly in the docs, would happily take a PR!

@radoslavirha
Copy link
Contributor Author

I'll try to implement it partially in the next weeks (there are tons of Joi validators on the routes). Maybe I'll find out something interesting and let you know!

I'm still in researching stage right now.

Thanks

@devinivy
Copy link
Member

devinivy commented Jan 25, 2023

If you want to change your validator piecemeal, you can also specify the validator in each individual route config. E.g. this would work:

server.route({
    method: 'post',
    path: '/validate',
    handler: () => ({ success: true }),
    options: {
        validate: {
            validator: zodValidator, // Can specify a validator just for this route
            payload: z.object({
                foo: z.number().int(),
                bar: z.string().optional()
            })
        }
    }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support Questions, discussions, and general support
Projects
None yet
Development

No branches or pull requests

3 participants