Schema validation
This guide will show you how to validate job data using schema validation libraries. Cadence MQ supports any library that implements the Standard Schema specification, including popular libraries like Zod, Valibot, and ArkType.
Why use schema validation?
Section titled “Why use schema validation?”Schema validation is optional but highly recommended. It ensures that your job data is properly typed and validated before scheduling a job. This helps catch errors early and provides better type safety throughout your application.
If you don’t provide a schema, the job data will be of type unknown
and no validation will be performed.
Using Valibot
Section titled “Using Valibot”Valibot is a lightweight schema validation library.
6 collapsed lines
import { createCadence } from '@cadence-mq/core';import { createMemoryDriver } from '@cadence-mq/driver-memory';import * as v from 'valibot';
const driver = createMemoryDriver();const cadence = createCadence({ driver });
// Register a task with Valibot schema validationcadence.registerTask({ taskName: 'process-order', schema: { data: v.object({ orderId: v.pipe(v.string(), v.uuid()), amount: v.pipe(v.number(), v.minValue(0)), itemsIds: v.array(v.string()), }), }, handler: async ({ data }) => { console.log(`Processing order ${data.orderId} for $${data.amount}`); },});
// Schedule a job with validated dataawait cadence.scheduleJob({ taskName: 'process-order', data: { orderId: 'order-123', amount: 99.99, items: ['item1', 'item2'], },});
Using Zod
Section titled “Using Zod”Zod is a TypeScript-first schema declaration and validation library.
6 collapsed lines
import { createCadence } from '@cadence-mq/core';import { createMemoryDriver } from '@cadence-mq/driver-memory';import * as z from 'zod';
const driver = createMemoryDriver();const cadence = createCadence({ driver });
// Register a task with Zod schema validationcadence.registerTask({ taskName: 'send-welcome-email', schema: { data: z.object({ email: z.string().email(), name: z.string().optional().default('User'), userId: z.number().int().positive(), }), }, handler: async ({ data }) => { // data is now strongly typed based on the schema console.log(`Sending welcome email to ${data.name} at ${data.email}`); },});
// This will throw a validation error if the data does not match the schemaawait cadence.scheduleJob({ taskName: 'send-welcome-email', data: { email: 'user@example.com', userId: 123, // name is optional and will default to 'User' },});
Error handling
Section titled “Error handling”When you schedule a job with invalid data, Cadence MQ will throw a validation error:
19 collapsed lines
import { createCadence } from '@cadence-mq/core';import { createMemoryDriver } from '@cadence-mq/driver-memory';import * as z from 'zod';
const driver = createMemoryDriver();const cadence = createCadence({ driver });
cadence.registerTask({ taskName: 'greet', schema: { data: z.object({ email: z.string().email(), name: z.string().optional().default('Ahsoka Tano'), }), }, handler: async ({ data }) => { console.log(`Greeting ${data.name} with email ${data.email}`); },});
try { // This will throw a validation error await cadence.scheduleJob({ taskName: 'greet', data: { email: 'invalid-email', // Invalid email format }, });} catch (error) { console.error('Validation error:', error.message); // Output: Validation error: Invalid email}
Type safety
Section titled “Type safety”When you define a schema for your task, the handler
function becomes strongly typed, if no schema is provided, the data
parameter will be of type unknown
.
Supported libraries
Section titled “Supported libraries”Cadence MQ supports any validation library that implements the Standard Schema specification. See the supported libraries section for a list of libraries that are known to be compatible.
Best practices
Section titled “Best practices”- Provide meaningful defaults: Use optional fields with defaults to make your schemas more flexible.
- Use specific validation rules: Instead of generic string validation, use specific validators like
email()
,url()
, oruuid()
. - Handle validation errors gracefully: Always wrap job scheduling in try-catch blocks when dealing with user input.
- Keep schemas in sync: When you update a task’s schema, make sure to update all code that schedules jobs for that task.
Schema structure
Section titled “Schema structure”The schema object should have a data
property that contains your validation schema:
schema: { data: yourValidationSchema, // Any Standard Schema compliant library}
The data
property is required and represents the job data that will be passed to your task handler.