How to validate JSON schema in Perl?

Question

How to validate JSON schema in Perl?

Validating JSON data against a JSON Schema in Perl involves parsing the JSON, then checking its structure and values according to rules defined in a schema document. JSON Schema validation ensures that the data complies with the expected format, types, and constraints, which is crucial for robust web services, APIs, and data processing pipelines.

Overview of JSON Schema Validation in Perl

Perl doesn't have native JSON Schema validation built into its core modules, but several CPAN modules make this easier. The most popular and modern choice is JSON::Validator. It fully supports JSON Schema Drafts (including versions 4, 6, and 7) and allows you to validate JSON data against a schema with detailed error reporting.

Here is what you typically do when validating JSON schema in Perl:

  • Parse the JSON data string into Perl data structures using JSON or JSON::MaybeXS.
  • Load the JSON Schema (either from a file or a Perl data structure).
  • Use a validation module like JSON::Validator to check the data against the schema.
  • Handle validation success or errors.

Perl Concepts Relevant Here

  • Sigils: Scalar $ for single values, array @ for lists, hash % for key-value pairs. JSON maps naturally to hashes and arrays.
  • Context: Validation functions may return true/false in scalar context or lists of errors in list context.
  • TMTOWTDI: You could write custom validation code, but using a dedicated CPAN module is simpler, safer, and maintainable.

Example Using JSON::Validator (Core-ish Modules Only)

JSON::Validator is widely used but requires installation from CPAN. However, for an environment without third-party modules, you cannot perform full JSON Schema validation. You can, however, do basic JSON parsing using JSON::PP (core since Perl 5.14) and write simple validation logic manually.

Below is a runnable example using JSON::PP to parse JSON and a minimal handcrafted validation that checks required keys and types without external schema libraries, illustrating what full validation looks like conceptually.

use strict;
use warnings;
use feature 'say';
use JSON::PP;

# Sample JSON data string
my $json_text = q|{
  "name": "Perl",
  "version": 5.32,
  "features": ["scalars", "arrays", "hashes"]
}|;

# Typical JSON Schema rules (conceptual):
# {
#   "type": "object",
#   "required": ["name", "version"],
#   "properties": {
#     "name": { "type": "string" },
#     "version": { "type": "number" },
#     "features": { "type": "array", "items": { "type": "string" } }
#   }
# }

# Decode JSON to Perl data structure
my $data = eval { JSON::PP->new->decode($json_text) };
if ($@) {
    die "Invalid JSON: $@";
}

# Simple validation function mimicking some schema rules
sub validate_simple {
    my ($data) = @_;
    
    # Check top-level is hashref
    return "Expected an object" unless ref $data eq 'HASH';

    # Check required keys
    for my $key (qw/name version/) {
        return "Missing required key: $key" unless exists $data->{$key};
    }

    # Check "name" is string
    return "'name' must be a string" unless !ref $data->{name};

    # Check "version" is a number (scalar, numeric)
    return "'version' must be a number" unless $data->{version} =~ /^[0-9]+(\.[0-9]+)?$/;

    # Check "features" is array of strings if exists
    if (exists $data->{features}) {
        return "'features' must be an array reference" unless ref $data->{features} eq 'ARRAY';
        for my $item (@{ $data->{features} }) {
            return "Each feature must be a string" if ref $item;
        }
    }

    return; # no error
}

my $error = validate_simple($data);
if ($error) {
    say "Validation failed: $error";
} else {
    say "Validation passed!";
}

Key Points

  • Using Existing Modules: For comprehensive JSON Schema validation, install JSON::Validator from CPAN:

use JSON::Validator;

my $validator = JSON::Validator->new;
$validator->schema($json_schema);  # Load your schema (hashref or file)
my $result = $validator->validate($data);

if ($result->has_errors) {
    print "Errors:\n";
    print $_->message . "\n" for $result->errors;
} else {
    print "Data is valid.\n";
}
  • This handles complex type checking, nested schemas, enums, pattern matching, and more.
  • Version Differences: JSON::PP is core since Perl 5.14, JSON::Validator supports multiple schema drafts.
  • Common Pitfall: Confusing JSON Schema validation with JSON parsing. Parsing only checks syntax, not semantics or constraints.

In summary, for advanced JSON schema validation in Perl, JSON::Validator is the recommended approach. If you cannot install modules, you are limited to manual checks after parsing with core JSON::PP. The example above demonstrates a simple, conceptual validation suitable for lightweight use or educational purposes.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 24ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Validation passed!
STDERR
(empty)

Was this helpful?

Related Questions