This notebook explores advanced techniques for building complex validation schemas with Joi, the powerful schema validation library for JavaScript. We'll cover nested objects, conditional validation, custom validators, and more to help you implement robust data validation in your Node.js applications.
$ npm install joi up to date in 425ms 28 packages are looking for funding run `npm fund` for details
Joi version: 17.13.3
Complex data often involves nested objects. Let's see how to validate them effectively.
Nested object validation result: { value: { id: '123e4567-e89b-12d3-a456-426614174000', username: 'johndoe', name: { first: 'John', middle: '', last: 'Doe' }, contact: { email: 'john.doe@example.com', phone: '555-123-4567' }, addresses: { home: [Object], shipping: [Object] } }, error: [Error [ValidationError]: "id" must be a valid GUID] { _original: { id: '123e4567-e89b-12d3-a456-426614174000', username: 'johndoe', name: [Object], contact: [Object], addresses: [Object] }, details: [ [Object] ] } }
Sometimes validation rules depend on other fields. Let's explore conditional validation.
Credit card payment validation: { value: { method: 'credit_card', cardNumber: '4111111111111111', expiryMonth: 12, expiryYear: 2026, cvv: '123' } }
PayPal payment validation: { value: { method: 'paypal', paypalEmail: 'user@example.com' } }
Invalid payment validation: { value: { method: 'credit_card', paypalEmail: 'user@example.com' }, error: [Error [ValidationError]: "cardNumber" is required] { _original: { method: 'credit_card', paypalEmail: 'user@example.com' }, details: [ [Object] ] } }
Let's explore validating arrays with complex items and constraints.
Complex order validation result: { value: { orderId: '123e4567-e89b-12d3-a456-426614174000', customerId: 'cust-12345', items: [ [Object], [Object] ], shippingAddress: { street: '123 Main St', city: 'Anytown', state: 'CA', zipCode: '12345' }, paymentMethod: { method: 'credit_card', cardNumber: '4111111111111111', expiryMonth: 12, expiryYear: 2026, cvv: '123' } }, error: [Error [ValidationError]: "orderId" must be a valid GUID] { _original: { orderId: '123e4567-e89b-12d3-a456-426614174000', customerId: 'cust-12345', items: [Array], shippingAddress: [Object], paymentMethod: [Object] }, details: [ [Object] ] } } Calculated total: undefined
Sometimes you need to validate objects with dynamic keys.
Content with dynamic metadata validation: { value: { id: 'article-123', title: 'Understanding Joi Validation', content: 'Joi is a powerful schema validation library...', type: 'article', metadata: { author: 'John Doe', published_date: '2023-05-15', read_time: 5, tags: [Array], featured: true, category: 'programming' } } }
Invalid metadata validation: { value: { id: 'article-456', title: 'Invalid Metadata Example', content: 'This example has invalid metadata...', type: 'article', metadata: { author: 'Jane Smith', '1invalid_key': 'This key starts with a number', tags: [Array] } }, error: [Error [ValidationError]: "metadata.1invalid_key" is not allowed] { _original: { id: 'article-456', title: 'Invalid Metadata Example', content: 'This example has invalid metadata...', type: 'article', metadata: [Object] }, details: [ [Object] ] } }
Let's validate fields that depend on each other.
Date range validation (without duration): { value: { startDate: 2023-01-01T00:00:00.000Z, endDate: 2023-01-05T00:00:00.000Z, duration: 4 } }
Date range validation (with correct duration): { value: { startDate: 2023-02-10T00:00:00.000Z, endDate: 2023-02-15T00:00:00.000Z, duration: 5 } }
Date range validation (with incorrect duration): { value: { startDate: 2023-03-20T00:00:00.000Z, endDate: 2023-03-25T00:00:00.000Z, duration: 10 }, error: [Error [ValidationError]: Error code "dateRange.durationMismatch" is not defined, your custom type is missing the correct messages definition] { _original: { startDate: '2023-03-20', endDate: '2023-03-25', duration: 10 }, details: [ [Object] ] } }
This notebook has demonstrated advanced techniques for building complex schemas with Joi:
These techniques enable you to build robust validation for even the most complex data structures in your JavaScript applications.
For more information, check out the Joi documentation.