Home > Back-end >  How to use zod with Prisma to validate user input
How to use zod with Prisma to validate user input

Time:12-12

I'm trying to use Zod and Prisma together and I ran into some problems with validation

in my user.model.ts file I have these validations using Zod

//user.mode.ts file

const userSchema = z.object({
  username: z.string({
    required_error: "Username field is required",
  }),
  email: z
    .string({
      required_error: "Email field is required",
      invalid_type_error: "This field must be in email format",
    })
    .email(),
  password: z
    .string({
      required_error: "Password field is required",
    })
    .min(6, "Password must be at least 6 characters"),

});

export type UserModel = z.infer<typeof userSchema>;

and in my user.service.ts file I have this one function that wants to use the validation in user.model.ts, I don't know if this is the way to use it

//user.service.ts file

export const createUser = async (
  username: string,
  email: string,
  password: string
) => {
  const user: UserModel = await prisma.user.create({
    data: {
      username: username,
      email: email,
      password: password,
    },
  });
  return user;
};

and this is how it looks like in authController.ts

//authController.ts file

export const signUpLogic = async (req: Request, res: Response) => {
  const { username, email, password } = req.body;
  try {
    const hashedPassword = await bcrypt.hash(password, 10);
    //
    createUser(username, email, String(hashedPassword));
    //

  } catch (err) {
    if (err instanceof PrismaClientKnownRequestError) {
      if (err.code === "P2002") {
        res.json({ message: "email already taken" });
      }
    }
  }
};

but when I run the code to test the validations, the terminal throws a prisma error that is supposed to be handled by the catch block instead of displaying the error message in postman.

And the validations are not working. I still can enter the wrong email format into the email field

an image of the database

CodePudding user response:

You are forgotting to use await inside signUpLogic.

And the validations are not working. I still can enter the wrong email format into the email field.

You are not using zod to parse the data.

You can do the following:

export const createUser = async ({ 
  username,
  email,
  password,
}: UserModel) => {
  const user: UserModel = await prisma.user.create({
    data: {
      username,
      email,
      password,
    },
  });
  return user;
};
export const signUpLogic = async (req: Request, res: Response) => {
  const { username, email, password } = req.body;
  try {
    const hashedPassword = await bcrypt.hash(password, 10);
    
    const result = userSchema.safeParse({ username, email, password: String(hashedPassword)});

    if(result.success) {
      await createUser(result.data);
    } else {
      // handle wrong parsing result
    }
  } catch (err) {
    if (err instanceof PrismaClientKnownRequestError) {
      if (err.code === "P2002") {
        res.json({ message: "email already taken" });
      }
    }
  }
};
  • Related