-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Guidance on creating slight schema variants for varied contexts #85
Comments
I think I've held off on documenting higher-order patterns because I have plans for implemented separate libraries on top of Zod for RPC, REST, GraphQL, and forms. Of course if someone beats me to it I won't be mad ;) Currently I'm already working on the ZodRPC package. This describes the full workflow for using Zod to implement an end-to-end typesafe API. It also includes out-of-the-box client side SDK generation which is pretty rad. I know you had a broader point but I'm going to go through your bullet points anyway. Maybe it'll shed light on how I think about things.
|
Thinking about this one a bit more. I'm wondering if it might make sense to generally solve this type of thing on the application side like this: // commonValidations.ts
import * as z from 'zod';
export const id = z.string().refine(val => val.length == 8, {
message: "Foreign keys should be 8 characters",
}); // clientValidations.ts
import * as z from 'zod';
import * as commonValidations from './commonValidations';
/*
Client does not have any extra validations for ID, so it uses common directly
*/
export const user = z.object({
id: commonValidations.id,
}); // serverValidations.ts
import * as z from 'zod';
// model only exists on the server, not implemented here
import { isValidId } from './applicationModel';
import * as commonValidations from './commonValidations';
export const id = commonValidations.id.refine(isValidId, {
message: 'ID is invalid',
});
export const user = z.object({
id,
}); What I like about this design is that everything is very explicit, clear, and avoids tight coupling between client and server. What I don't like is that it could get pretty verbose with lots of redundancy across the client and server as the schema gets more complex. That is, if |
I think your example is a good reference for best-practices code sharing between client and schema. Closing for now - I'm not sure how to act on this. There isn't much guidance I could give that would be generally applicable besides maybe "don't repeat yourself". Future readers: if there's a particular feature that would help you avoid redundancy then by all means create a new issue for it. |
Yeah, agreed that at this point there isn't really an obvious action to take here. From investigating this, I've found that it's mostly easiest to make shared types from the leaf nodes up as high as what is fully shared, then do a hard fork where the types diverge. It can get pretty redundant with deeply nested types that diverge near the leaves, but I've found that the redundancy is the clearest way to represent this, rather than abstractions or core feature additions. |
I appreciate that this issue is closed. Having said that, is there any guidance either of you can share with us, given the current features supported by the library? Thank you in advance |
I am interested in using zod for frontend, API, and backend validation.
For example, a browser might validate user inputs live as they are changed on the page. The user hits "submit" which sends the data to the API. The API runs its own validations on this data that may be somewhat different. The API changes the data slightly to conform with the backend needs. The backend has a similar schema, but there are some small differences.
Differences might be things like:
I'm not necessarily looking for changes to the library, but rather recommended patterns through documentation, blog posts, etc. I see that zod supports merging, masking, and extending, but am looking for higher level guidance on patterns for this type of use case. I can see schema sharing as something that could potentially make a codebase much more complex without due care. The guidance here might be to create separate schemas because the costs of coupling schemas across contexts is too high!
There may also be features that could be added to zod that make this use case easier.
The text was updated successfully, but these errors were encountered: