WayrApp Backend & Ecosystem Documentation - v1.0.0
    Preparing search index...

    Function validate

    • Primary validation middleware factory for comprehensive request data validation

      Creates Express middleware that validates incoming HTTP requests against Zod schemas for body, parameters, and query string data. This function serves as the core validation mechanism for the WayrApp backend API, ensuring all incoming data conforms to expected structures before reaching route handlers and business logic layers.

      The middleware performs validation in a specific order: body, parameters, then query parameters. Each validation step transforms and validates the corresponding request data, automatically coercing types where appropriate (e.g., string to number conversions). If validation succeeds, the validated and transformed data replaces the original request data, ensuring type safety throughout the request lifecycle.

      When validation fails, the middleware automatically forwards Zod validation errors to the global error handler, which transforms them into standardized API error responses. This ensures consistent error formatting and proper HTTP status codes for all validation failures.

      The function is designed for high performance with minimal overhead, utilizing Zod's efficient parsing engine and avoiding unnecessary data copying. It supports complex nested schemas, conditional validation, custom transformations, and all Zod validation features.

      Security features include automatic sanitization of input data, prevention of prototype pollution attacks through safe object parsing, and protection against type confusion attacks by enforcing strict schema adherence. The middleware also includes safeguards against denial-of-service attacks through efficient validation algorithms.

      Parameters

      • schema: {
            body?: ZodType<any, ZodTypeDef, any>;
            params?: ZodType<any, ZodTypeDef, any>;
            query?: ZodType<any, ZodTypeDef, any>;
        }

        Configuration object containing Zod schemas for different request parts

        • Optionalbody?: ZodType<any, ZodTypeDef, any>

          Optional Zod schema for validating request body data

        • Optionalparams?: ZodType<any, ZodTypeDef, any>

          Optional Zod schema for validating URL parameters

        • Optionalquery?: ZodType<any, ZodTypeDef, any>

          Optional Zod schema for validating query string parameters

      Returns (req: Request, _res: Response, next: NextFunction) => void

      Express middleware function that performs the validation

      When validation fails, forwards Zod validation errors to error handler

      When non-Zod errors occur during validation process

      // Validate only request body
      const userSchema = z.object({
      name: z.string().min(1, 'Name is required'),
      email: z.string().email('Invalid email format'),
      age: z.number().int().min(13, 'Must be at least 13 years old')
      });

      router.post('/users', validate({ body: userSchema }), userController.create);
      // Validate URL parameters only
      const paramSchema = z.object({
      id: z.string().uuid('Invalid user ID format'),
      courseId: z.string().uuid('Invalid course ID format')
      });

      router.get('/users/:id/courses/:courseId', validate({ params: paramSchema }), handler);
      // Validate query parameters with transformations
      const querySchema = z.object({
      page: z.string().transform(val => parseInt(val, 10)).pipe(z.number().int().min(1)),
      limit: z.string().transform(val => parseInt(val, 10)).pipe(z.number().int().min(1).max(100)),
      search: z.string().optional(),
      sortBy: z.enum(['name', 'createdAt', 'updatedAt']).optional()
      });

      router.get('/courses', validate({ query: querySchema }), courseController.list);
      // Comprehensive validation for complex endpoints
      const updateCourseSchema = {
      params: z.object({
      id: z.string().uuid('Invalid course ID')
      }),
      body: z.object({
      title: z.string().min(1, 'Title is required').max(200, 'Title too long'),
      description: z.string().optional(),
      isPublished: z.boolean().optional(),
      tags: z.array(z.string()).max(10, 'Too many tags').optional()
      }),
      query: z.object({
      notify: z.string().transform(val => val === 'true').pipe(z.boolean()).optional()
      })
      };

      router.put('/courses/:id', validate(updateCourseSchema), courseController.update);
      // Nested object validation
      const lessonSchema = z.object({
      title: z.string().min(1),
      content: z.object({
      type: z.enum(['video', 'text', 'interactive']),
      data: z.object({
      url: z.string().url().optional(),
      text: z.string().optional(),
      exercises: z.array(z.object({
      question: z.string(),
      answer: z.string()
      })).optional()
      })
      })
      });

      router.post('/lessons', validate({ body: lessonSchema }), lessonController.create);