Any clue to implement zod client side?

Hello !

I would like to use zod on both web and api to avoid double validation setting and keep integrity. Is it a way to use “@hookform/resolvers/zod” with pls ? If not is it a way to see the code of this component and Form to add a custom component to be complient with the form error interface ? couldn’t find it on the github. Im coming from angular and im a bit lost with react so any clue would help a lot :slight_smile:

Thank you in advance

1 Like

So I finished by using symlink as it’s such a pain to make the api side work correctly. I wrote an article about my path if you are interested for… Enhancing Redwood: A Guide to Implementing Zod for Data Validation and Schema Sharing Between the API and Web Layers - DEV Community

2 Likes

@growms :wave: I cross posted your article to our discord #rw-related-content channel. :slightly_smiling_face:

1 Like

I have created schemas in a folder under api/src/schema/
I can import them within my services and validate with:

  validate(input, {
    custom: {
      message: 'Wrong format for input',
      with: () => {
        if (input.properties) {
          const parsed = MySchema.safeParse(input)
          if (!parsed.success) {
            throw new Error('Wrong format for input')
          }
        }
      },
    },
  })

Could be nicer, but i mainly use it for json fields and otherwise stick to redwood validation.

And client side i import via import {MySchema} from 'api/src/schema/MySchema
and can use it there.
I guess then it should be rather easy to integrate with hookform too.
But having the redwood roundtrip would be nice, too.

Not sure if it is important, but right now i have zod in my package.json and api/package.json. Maybe the latter is not necessary…

Imho it’s important to have only one module taking care of validation in order to scale correctly. What i’ve done is just symlinking the schema to be able to use it both sides and adding a handler to map Zod error in Redwood like error. It integrates wonderfully and it remove boilerlpating on validation both sides. You still can use the FormError and FieldError the redwood way. Feel free to check my article !

What’s really missing to me is an official way to share libs between the 2 projects which supports typescript, testing and deployment. I fall back on symlink after 3 hours tryings to make it works throught babel/tsconfig/webpack… Symlink is nice but then you have to take care of the existence of the directory before building and the existence of the symlink at the installation and this is scratching me a bit :wink:

The discord link is not working, is it public ?
Edit : it’s ok i gone thourgh the server (RedwoodJS) and found it. Ty i didn’t know there was a discord server.

1 Like

Is it not possible to just import import { MySchema } from 'api/src/schema/MySchema' ?
Worked for me, no symlink.
It is just important to avoid imports to other api files. Then it should be fine.

(The reason why I placed zod in my api/package.json is because of docker building api side seperatly)

I will have a look at your FormError/FieldError validation. Thats definitely nice!

I’m not sure it would work when building… Though my solution doesn’t work either by itself; you have to copy the folder before build. What doesn’t sit right with me is referencing a server tree from a client tree… I find that quite unsettling. In my opinion, the two sides of the code should be completely independent. I placed the code in the ‘api’ directory, but ideally, it should be its own independent package. I just thought, “well if i have other clients it’s better in api than in web workspace” :wink:

I agree on the referencing! It is something that bothers me, too. Right now I have to check manually, that my schemas do not import other parts of api side. So actually having a package/workspace to import from might not be a bad idea! And making it encapsualated, so it does not import from api or web at all. Going to try this, when I find time.
My experience with workspaces within redwood was just not so great so far. It is possible, but when importing into my workspace from i.e. web side, I often loose types. But since I dont need to import, this might work well.
Importing to web side so far works great. Just add "my_package_name": "workspace:packages/myPackage" to web/package.json and then imports should work like 'import foo from ‘my_package_name/src/foo’`