DEV Community

John  Ajera
John Ajera

Posted on

Simplifying JSON Validation with Ajv (Another JSON Validator)

Simplifying JSON Validation with Ajv (Another JSON Validator)

Introduction

For the full implementation, you can reference the GitHub repository: https://github.com/jdevto/ajv-demo

Ajv (Another JSON Validator) is a popular tool for validating JSON data against schemas. By default, Ajv uses the older Draft-07 of JSON Schema, but with some additional effort, it can be configured to work seamlessly with the newer Draft 2019-09. In this article, we will demonstrate how to use Ajv with the newer Draft 2019-09, ensuring your JSON data validation leverages the latest schema features.

  • meta-data.json
  • format.json
  • content.json
  • json-schema-draft-2019-09.json

You can download these meta-schemas from the official JSON Schema repository:

curl -L -o schemas/core.json https://json-schema.org/draft/2019-09/meta/core
curl -L -o schemas/applicator.json https://json-schema.org/draft/2019-09/meta/applicator
curl -L -o schemas/validation.json https://json-schema.org/draft/2019-09/meta/validation
curl -L -o schemas/meta-data.json https://json-schema.org/draft/2019-09/meta/meta-data
curl -L -o schemas/format.json https://json-schema.org/draft/2019-09/meta/format
curl -L -o schemas/content.json https://json-schema.org/draft/2019-09/meta/content
curl -L -o schemas/json-schema-draft-2019-09.json https://json-schema.org/draft/2019-09/schema
Enter fullscreen mode Exit fullscreen mode

Code Example

Below is the code for validating JSON data against a schema using Ajv and Draft 2019-09:

const Ajv2019 = require("ajv/dist/2019");
const addFormats = require("ajv-formats");
const fs = require("fs");
const path = require("path");

// Initialize Ajv2019 instance
const ajv = new Ajv2019({ strict: false });

// List of meta-schemas to load
const metaSchemas = [
  "core.json",
  "applicator.json",
  "validation.json",
  "meta-data.json",
  "format.json",
  "content.json",
  "json-schema-draft-2019-09.json",
];

// Load and add meta-schemas if not already registered
metaSchemas.forEach((file) => {
  const schema = JSON.parse(fs.readFileSync(path.join(__dirname, "schemas", file), "utf8"));
  if (!ajv.getSchema(schema.$id)) {
    ajv.addMetaSchema(schema);
  } else {
    console.log(`Meta-schema "${schema.$id}" already added. Skipping.`);
  }
});

// Add format validation support
addFormats(ajv);

// Define a schema using Draft 2019-09
const schema = {
  $schema: "https://json-schema.org/draft/2019-09/schema",
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "integer", minimum: 0 },
  },
  required: ["name", "age"],
};

// Sample data to validate
const validData = { name: "Alice", age: 25 };
const invalidData = { name: "Bob", age: -5 };

try {
  const validate = ajv.compile(schema);

  [validData, invalidData].forEach((data, index) => {
    if (validate(data)) {
      console.log(`✅ Validation succeeded for sample ${index + 1}.`);
    } else {
      console.error(`❌ Validation failed for sample ${index + 1}:`);
      console.error(validate.errors);
    }
  });
} catch (error) {
  console.error("❌ Error compiling schema:", error.message);
}
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code

  1. Initializing Ajv2019: We use the Ajv2019 module specifically for Draft 2019-09 schemas. The strict mode is disabled for compatibility.

  2. Registering Meta-Schemas: The meta-schemas are dynamically loaded from the schemas directory and registered with Ajv.

  3. Adding Format Validation: The addFormats function enhances Ajv by enabling support for common JSON formats like email, uri, etc.

  4. Defining a Schema: The schema specifies:

  • A name property (string, required).
  • An age property (integer, required, must be ≥ 0).
  1. Compiling and Validating Data:
  • The validData object passes validation.
  • The invalidData object fails because age is negative.

Running the Code

  1. Save the code to a file (e.g., validate.js).
  2. Ensure the schemas directory contains all required meta-schemas.
  3. Run the script:
   node validate.js
Enter fullscreen mode Exit fullscreen mode

Expected output:

Meta-schema "https://json-schema.org/draft/2019-09/meta/core" already added. Skipping.
...
✅ Validation succeeded for sample 1.
❌ Validation failed for sample 2:
[
  {
    instancePath: "/age",
    schemaPath: "#/properties/age/minimum",
    keyword: "minimum",
    params: { comparison: ">=", limit: 0 },
    message: "must be >= 0"
  }
]
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. Meta-Schema Management:
  • Properly register all meta-schemas to avoid unresolved references.
  1. Error Reporting:
  • Ajv provides detailed error messages for failed validations.
  1. Extensibility:
  • This setup can easily be extended for more complex schemas and data validations by adding additional meta-schemas or customizing validation rules. For instance, you could include custom keywords, validate dynamic data structures, or support nested schemas to handle advanced use cases.

Conclusion

For the complete code and examples, visit the GitHub repository: https://github.com/jdevto/ajv-demo

Validating JSON data using Ajv with Draft 2019-09 is straightforward if you handle meta-schemas correctly. This approach ensures that your data adheres to the latest JSON Schema standards while leveraging Ajv's powerful validation capabilities. By automating meta-schema registration, you can streamline the validation process and reduce potential errors.

Top comments (0)