This notebook provides a comprehensive guide to Joi, the powerful schema description language and data validator for JavaScript. We'll explore advanced schema building techniques, validation strategies, and real-world examples 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
Let's start by understanding the core components of Joi schemas and how to build them effectively.
Basic schema types: String schema: { type: 'string' } Number schema: { type: 'number' } Boolean schema: { type: 'boolean' }
Complex user schema structure: { "type": "object", "keys": { "id": { "type": "string", "rules": [ { "name": "guid", "args": { "options": { "version": "uuidv4" } } } ] }, "username": { "type": "string", "flags": { "presence": "required" }, "rules": [ { "name": "alphanum" }, { "name": "min", "args": { "limit": 3 } }, { "name": "max", "args": { "limit": 30 } } ] }, "email": { "type": "string", "flags": { "presence": "required" }, "rules": [ { "name": "email", "args": { "options": { "tlds": { "allow": false } } } } ] }, "password": { "type": "string", "flags": { "presence": "required" }, "rules": [ { "name": "pattern", "args": { "regex": "/^[a-zA-Z0-9]{8,30}$/" } } ] }, "birthYear": { "type": "number", "rules": [ { "name": "integer" }, { "name": "min", "args": { "limit": 1900 } }, { "name": "max", "args": { "limit": 2025 } } ] }, "createdAt": { "type": "date", "flags": {} }, "roles": { "type": "array", "flags": { "default": [ "user" ] }, "items": [ { "type": "string", "flags": { "only": true }, "allow": [ "user", "admin", "editor" ] } ] } } }
Learn how to compose and reuse schemas for better maintainability.
Login validation result: { value: { email: 'user@example.com', password: 'Password123', rememberMe: false } }
Registration validation result: { value: { username: 'johndoe', email: 'john@example.com', password: 'Password123', confirmPassword: 'Password123', createdAt: 1741806806068 } } Created timestamp type: number
Explore advanced string validation techniques for common use cases.
URL validation: Valid URL: { value: 'https://example.com' } Invalid URL: { value: 'ftp://example.com', error: [Error [ValidationError]: "value" must be a valid uri with a scheme matching the http|https pattern] { _original: 'ftp://example.com', details: [ [Object] ] } }
Credit card validation: Valid card: { value: '4111111111111111' } Invalid card: { value: '1234567812345678', error: [Error [ValidationError]: "value" must be a credit card] { _original: '1234567812345678', details: [ [Object] ] } }
Explore advanced number and date validation techniques.
Number validation examples: Integer validation: { value: 42 } Integer validation (invalid): { value: 42.5, error: [Error [ValidationError]: "value" must be an integer] { _original: 42.5, details: [ [Object] ] } } Precision validation: { value: 99.99 } Multiple of 5 validation: { value: 25 } Multiple of 5 validation (invalid): { value: 27, error: [Error [ValidationError]: "value" must be a multiple of 5] { _original: 27, details: [ [Object] ] } }
Date validation examples: Past date validation: { value: 2020-01-01T00:00:00.000Z } Future date validation: { value: 2026-03-12T19:13:32.678Z } ISO date validation: { value: 2023-05-15T14:30:00.000Z }
Explore advanced techniques for object schema validation.
Metadata validation with pattern keys: { value: { id: '123', name: 'Test Item', meta_color: 'blue', meta_size: 'large', meta_material: 'cotton' } }
Strict schema validation (unknown keys rejected): { value: { name: 'John', age: 30, country: 'USA' }, error: [Error [ValidationError]: "country" is not allowed] { _original: { name: 'John', age: 30, country: 'USA' }, details: [ [Object] ] } }
Flexible schema validation (unknown keys allowed): { value: { name: 'John', age: 30, country: 'USA' } }
Credit card payment validation: { value: { paymentMethod: 'credit_card', cardNumber: '4111111111111111', expiryDate: '12/25' } }
PayPal payment validation (with forbidden field): { value: { paymentMethod: 'paypal', paypalEmail: 'user@example.com', cardNumber: '4111111111111111' }, error: [Error [ValidationError]: "cardNumber" is not allowed] { _original: { paymentMethod: 'paypal', paypalEmail: 'user@example.com', cardNumber: '4111111111111111' }, details: [ [Object] ] } }
Explore advanced techniques for array schema validation.
Basic array validation: Valid tags: { value: [ 'javascript', 'nodejs', 'validation' ] } Invalid tags (too many): { value: [ 'a', 'b', 'c', 'd', 'e', 'f' ], error: [Error [ValidationError]: "value" must contain less than or equal to 5 items] { _original: [ 'a', 'b', 'c', 'd', 'e', 'f' ], details: [ [Object] ] } }
Ordered array validation: Valid 2D coordinates: { value: [ 10, 20 ] } Valid 3D coordinates: { value: [ 10, 20, 30 ] } Invalid coordinates (missing y): { value: [ 10 ], error: [Error [ValidationError]: "value" does not contain 1 required value(s)] { _original: [ 10 ], details: [ [Object] ] } }
Mixed array validation: Valid mixed array: { value: [ 'hello', 42, true, 'world' ] } Invalid mixed array: { value: [ 'hello', 42, true, { key: 'value' } ], error: [Error [ValidationError]: "[3]" does not match any of the allowed types] { _original: [ 'hello', 42, true, [Object] ], details: [ [Object] ] } }
Unique array validation: Valid unique array: { value: [ 'a', 'b', 'c' ] } Invalid unique array: { value: [ 'a', 'b', 'a' ], error: [Error [ValidationError]: "[2]" contains a duplicate value] { _original: [ 'a', 'b', 'a' ], details: [ [Object] ] } }
Complex array validation: Valid users array: { value: [ { id: 1, name: 'John', email: 'john@example.com' }, { id: 2, name: 'Jane', email: 'jane@example.com' } ] }
Explore advanced conditional validation techniques.
Basic conditional validation: Valid admin user: { value: { role: 'admin', permissions: [ 'read', 'write', 'delete' ] } } Invalid admin user (missing permissions): { value: { role: 'admin' }, error: [Error [ValidationError]: "permissions" is required] { _original: { role: 'admin' }, details: [ [Object] ] } } Valid regular user (no permissions needed): { value: { role: 'user' } }
Standard shipping validation: { value: { shippingMethod: 'standard', domesticAddress: { street: '123 Main St', city: 'Anytown', state: 'CA', zipCode: '12345' } } }
Express shipping validation: { value: { shippingMethod: 'express', domesticAddress: { street: '123 Main St', city: 'Anytown', state: 'CA', zipCode: '12345' }, phoneNumber: '1234567890' } }
International shipping validation: { value: { shippingMethod: 'international', internationalAddress: { street: '123 Global Ave', city: 'London', postalCode: 'SW1A 1AA', country: 'United Kingdom' } } }
Invalid shipping validation: { value: { shippingMethod: 'international', domesticAddress: { street: '123 Main St', city: 'Anytown', state: 'CA', zipCode: '12345' } }, error: [Error [ValidationError]: "domesticAddress" is not allowed] { _original: { shippingMethod: 'international', domesticAddress: [Object] }, details: [ [Object] ] } }
Create custom validation logic for complex requirements.
Valid product validation: { value: { name: 'Wireless Headphones', price: 99.99, salePrice: 79.99, quantity: 50, category: 'Electronics', tags: [ 'wireless', 'audio', 'bluetooth' ] } }
Invalid product validation (sale price too high): { value: { name: 'Wireless Headphones', price: 99.99, salePrice: 109.99, quantity: 50, category: 'Electronics', tags: [ 'wireless', 'audio', 'bluetooth' ] }, error: [Error [ValidationError]: Error code "product.invalidSalePrice" is not defined, your custom type is missing the correct messages definition] { _original: { name: 'Wireless Headphones', price: 99.99, salePrice: 109.99, quantity: 50, category: 'Electronics', tags: [Array] }, details: [ [Object] ] } }
Learn how to transform data and set default values during validation.
Blog post with transformations and defaults: { value: { title: 'Introduction to Joi Schema Validation', content: 'This is a comprehensive guide to using Joi for schema validation in your Node.js applications. We will cover basic and advanced validation techniques.This is a comprehensive guide to using Joi for schema validation in your Node.js applications. We will cover basic and advanced validation techniques.This is a comprehensive guide to using Joi for schema validation in your Node.js applications. We will cover basic and advanced validation techniques.', author: 'John Doe', tags: [], status: 'draft', createdAt: 1741806838238, views: 0, featured: false, slug: 'introduction-to-joi-schema-validation', excerpt: 'This is a comprehensive guide to using Joi for schema validation in your Node.js applications. We will cover basic and advanced validation techniques....' } }
Learn how to extend Joi with custom types and validation rules.
Book validation with ISBN-10: { value: { title: 'JavaScript: The Good Parts', author: 'Douglas Crockford', isbn10: '0596517742', publisher: "O'Reilly Media", publicationYear: 2008 } }
Book validation with ISBN-13: { value: { title: 'Eloquent JavaScript', author: 'Marijn Haverbeke', isbn13: '9781593279509', publisher: 'No Starch Press', publicationYear: 2018 } }
Book validation without ISBN: { value: { title: 'Some Book', author: 'Some Author', publisher: 'Some Publisher', publicationYear: 2020 }, error: [Error [ValidationError]: "value" must contain at least one of [isbn10, isbn13]] { _original: { title: 'Some Book', author: 'Some Author', publisher: 'Some Publisher', publicationYear: 2020 }, details: [ [Object] ] } }
Book validation with invalid ISBN: { value: { title: 'Invalid ISBN Book', author: 'Test Author', isbn10: '123456789', publisher: 'Test Publisher', publicationYear: 2021 }, error: [Error [ValidationError]: "isbn10" must be a valid ISBN-10] { _original: { title: 'Invalid ISBN Book', author: 'Test Author', isbn10: '123456789', publisher: 'Test Publisher', publicationYear: 2021 }, details: [ [Object] ] } }
This notebook has provided a comprehensive guide to building and validating schemas with Joi. We've covered:
Joi provides a powerful, flexible system for data validation in JavaScript applications. By leveraging these techniques, you can ensure data integrity, improve error handling, and create more robust applications.
For more information, check out the Joi documentation.