-
-
Notifications
You must be signed in to change notification settings - Fork 678
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
Validation using zod #1462
Comments
An example using |
I have no experience with |
I guess there is a question how much and are we gonna allow for zod to validate. For example this plugin for nest https://github.com/incetarik/nestjs-graphql-zod allows to validate nested objects too. Agnostic approach for type-graphql could be nice, for example if we can assign some metadata to specific field and then access it in validation function, this will allow integrate any validation library with type-graphql. If we just have access to field metadata then writing zod validation function is quite trivial: @InputType()
class Bar {
@Extensions({ zodSchema: z.string() }) // some way to assign metadata to the function
@Field()
field: string;
}
const schema = await buildSchema({
// ...other options
validate: (argValue, argType, fieldMetadata) => {
// we just need to access extensions metadata in this validate function
fieldMetadata?.zodSchema.parse(argValue) // this will throw on validation error
// the above same as `z.string().parse(argValue)`
},
}); I do not know anything about how hard is to implement this for type-graphql, it is just as an example idea |
@InputType()
class Bar {
@Zod(z => z.string()) // some way to assign metadata to the function
@Field()
field: string;
}
validate: (argValue, argType) => {
zodDecorators.validate(argType, argValue); // reads validation schema from own storage for `argType` class and parse `argValue` value
}, |
I have just tried to create a custom validator for any args passed to a graphql query or mutation: import { createMethodDecorator, ArgumentValidationError } from 'type-graphql';
import { ValidationError } from 'class-validator';
import { z } from 'zod';
type SchemaMap = { [argName: string]: z.Schema<any> };
function convertZodErrorToClassValidatorError(zodError: z.ZodError, argName: string): ValidationError[] {
return zodError.errors.map((error) => {
const validationError = new ValidationError();
validationError.property = argName;
validationError.constraints = { [error.code]: error.message };
return validationError;
});
}
export function ZodValidate(schemaMap: SchemaMap) {
return createMethodDecorator(async ({ args }, next) => {
for (const argName in schemaMap) {
const schema = schemaMap[argName];
const argValue = args[argName];
const result = schema.safeParse(argValue);
if (!result.success) {
const validationErrors = convertZodErrorToClassValidatorError(result.error, argName);
throw new ArgumentValidationError(validationErrors);
}
}
return next();
});
} Usage example: @InputType()
export class TestInput {
@Field()
targetAudience: string;
@Field()
annualLaunches: string;
@Field(() => Float)
employees: number;
}
....
const schema = z.object({ targetAudience: z.string().max(3), annualLaunches: z.string(), employees: z.number() });
@Mutation(() => Boolean)
@ZodValidate({ input: schema })
async zodValidated(@Arg('input') input: TestInput): Promise<boolean> {
console.log(input);
return true;
} And it validates as expected but the problem is that the output error is not formatted properly (the extensions exception doesnt include any validation errors paased to the ArgumentValidationError constructor):
Any idea why this happens @MichalLytek? |
I think that ref: colinhacks/zod#2099 (comment) my situation: i want to validate GraphQl input objects and fields list: required fields are depending on |
I would like to add on top of this as I am in need of a similar configuration and eventually came to a similar solution. |
Is your feature request related to a problem? Please describe.
Since my project extensively uses zod I want to be able validate
InputType
s and maybeObjectType
s too using zod.Describe the solution you'd like
something like this?
Describe alternatives you've considered
Using built in
class-validator
orjoiful
as described here => https://typegraphql.com/docs/validation.html#custom-validatorAdditional context
joiful
does not seem to be well maintained.class-validator
seems not bad butzod
is already quite popular library with friendly and understandable API having high flexibility and customization. So it might be worth to integrate zod withtype-graphql
.I feel like it is already possible to do it with zod by using Extension decorator => https://typegraphql.com/docs/extensions.html and custom validation function => https://typegraphql.com/docs/validation.html#custom-validator but I did not find examples in docs how to do that.
Basically how to extract extensions data in custom validation function?
If it is possible, I can even maybe contribute to add examples with zod validation if needed and someone can give me direction of where to start and where to look for...
So what would be the best way to integrate zod with typegraphql?
The text was updated successfully, but these errors were encountered: