Skip to main content

A fast, simple, user-friendly JSON Schema validator powered by Rust

Project description

rsonschema

Crates.io docs.rs PyPI CI License

A fast, simple, and user-friendly JSON Schema validator for Rust, with Python bindings.

Prologue

In the world of data validation, ensuring your data conforms to a specified structure is crucial.

At hiop, we sought a language-agnostic format to define how data should be structured, and JSON Schema stood out as the perfect solution.

This inspired the creation of rsonschema, a fast, simple, and user-friendly JSON Schema validator for Rust.

Why Rust?

Rust is celebrated for its performance and safety capabilities. These attributes make it an excellent choice for building a fast, user-friendly, secure, and efficient validator.

Alternatives

  • jsonschema: was previously our choice, offering robust validation but suffering from complex error handling. For example:

    1. jsonschema::error::ValidationError borrows the instance attribute, adding complexity.
    2. it lacks useful error messages for end users, especially when validating schemas with Schema Composition failures.
  • valico: like jsonschema, it has complex error handling. Moreover it is not actively maintained.

  • schemars: a de facto standard for schema generation with over 19 million downloads. However, it lacks validation APIs.

Usage

Rust

Add rsonschema to your Cargo.toml:

cargo add rsonschema

Here's how you can start using rsonschema in your Rust project:

let schema = serde_json::json!({
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "minLength": 3
});

let instance = serde_json::json!("foo");
let report = rsonschema::validate(
    &instance,
    schema.clone(),
);
assert!(report.is_valid());

let instance = serde_json::json!("a");
let report = rsonschema::validate(
    &instance,
    schema,
);
assert_eq!(
    report,
    rsonschema::ValidationReport {
        errors: Some(
            rsonschema::error::ValidationErrors::from([
                rsonschema::error::ValidationError {
                    instance: serde_json::json!("a"),
                    type_: rsonschema::error::type_::ValidationErrorType::MinLength {
                        limit: 3.into(),
                    },
                    ..Default::default()
                }
            ])
        ),
        ..Default::default()
    }
);

Python

Install from PyPI (requires Python >= 3.10):

pip install rsonschema
import rsonschema

schema = {"$schema": "https://json-schema.org/draft/2020-12/schema", "minLength": 3}

# validate(instance, schema, pointer=None, ref_resolver=None)
errors = rsonschema.validate("foo", schema, None, None)
assert errors == []

errors = rsonschema.validate("a", schema, None, None)
assert len(errors) == 1
assert str(errors[0])  # human-readable error description

Error Messages

One of rsonschema's key strengths is the quality of its human-readable error messages. Each error includes the failing value, the full path to it within the document, and a precise description — making them suitable to display directly to end users.

Simple constraint violation

let schema = serde_json::json!({
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "string",
    "minLength": 5
});

let report = rsonschema::validate(&serde_json::json!("hi"), schema);
let error = report.errors.unwrap().into_iter().min().unwrap();
println!("{error}");
// "hi": must be longer than `5` characters

Nested objects

The pointer tracks the full path from the document root to the failing value:

let schema = serde_json::json!({
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "properties": {
        "user": {
            "required": ["name", "email"]
        }
    }
});

let report = rsonschema::validate(
    &serde_json::json!({"user": {"name": "Alice"}}),
    schema,
);
let error = report.errors.unwrap().into_iter().min().unwrap();
println!("{error}");
// {"name":"Alice"} at `user`: missing required: `email`

Schema composition (anyOf, oneOf, allOf)

When validation fails on a composition keyword, rsonschema surfaces the most relevant inner error rather than a generic "did not match any schema" message. Relevance is determined by how closely the instance resembles each branch, using string similarity on values and property names.

let schema = serde_json::json!({
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "anyOf": [
        {"type": "string", "minLength": 5},
        {"type": "integer", "minimum": 10}
    ]
});

let report = rsonschema::validate(&serde_json::json!("hi"), schema);
let error = report.errors.unwrap().into_iter().min().unwrap();
println!("{error}");
// "hi": must be longer than `5` characters

"hi" is clearly closer to the string branch, so the minLength error from that branch is surfaced instead of a generic composition failure.

Python bindings

The same messages are available via the .message attribute on each error object:

import rsonschema

schema = {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "properties": {
        "user": {"required": ["name", "email"]}
    },
}
errors = rsonschema.validate({"user": {"name": "Alice"}}, schema, None, None)
print(str(errors[0]))
# {"name":"Alice"} at `user`: missing required: `email`

Performance

rsonschema is benchmarked against jsonschema across representative scenarios. Selected results on Apple M3 (lower is better):

Scenario rsonschema jsonschema (cold)
Simple string validation 738 ns 2.14 µs
Complex object (5 fields) 6.85 µs 8.95 µs
Array of 50 objects 54.0 µs 7.74 µs
anyOf composition 3.25 µs 4.91 µs

Cold means the competitor also compiles the schema on every call, matching rsonschema's usage model. See BENCHMARKS.md for the full methodology and results, including Python bindings.

Scope

rsonschema targets a specific, well-defined subset of JSON Schema:

  • Draft: only the latest (2020-12) specification is supported. Older drafts are not.
  • Validation only: the library validates instances against schemas and reports errors — it does not generate schemas or produce annotation output.
  • All standard keywords are implemented, including schema composition (allOf, anyOf, oneOf, not), conditionals (if/then/else), references ($ref, $anchor), unevaluated keywords (unevaluatedProperties, unevaluatedItems), and format assertions.
  • Intentionally unsupported: dynamic keywords $dynamicAnchor and $dynamicRef are excluded because they introduce significant complexity with limited practical benefit.

All official JSON Schema Test Suite tests, located in the tests folder, pass — except for the unsupported dynamic keywords above.

Community

Contribution

We firmly believe that collaboration is the key to innovation!

If you find a bug or have a feature request, please open an issue. If you want to go further and tackle it, open a pull request on our GitHub repository.

See CONTRIBUTING.md for development guidelines.

License

rsonschema is licensed under the Apache-2.0 License. See the LICENSE file for more details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rsonschema-0.1.16-cp314-cp314-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

rsonschema-0.1.16-cp314-cp314-macosx_10_12_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

rsonschema-0.1.16-cp312-cp312-win_amd64.whl (3.0 MB view details)

Uploaded CPython 3.12Windows x86-64

rsonschema-0.1.16-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.6 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

File details

Details for the file rsonschema-0.1.16-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rsonschema-0.1.16-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6fe5ae7647ebbd2ae6dcfae8364f1d07716753fc3cfbbbd52d753238b31fa883
MD5 140d3fa31d04702170665e7a8eccd71c
BLAKE2b-256 ddbf89253459ece3a5b701cb6b1143e6e0a85ef0d7386a0802c7049800bec08a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rsonschema-0.1.16-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on hiop-oss/rsonschema

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rsonschema-0.1.16-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rsonschema-0.1.16-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 90d55f704358c391d610ae3287b3077a5188086fb297f4373d4902b19a35b372
MD5 d4169a253be87336ef448ee6e1dc64dc
BLAKE2b-256 26e0c0000426ca71f776b278db504ef974f8111f8a4af90aa9389dc3f6d88299

See more details on using hashes here.

Provenance

The following attestation bundles were made for rsonschema-0.1.16-cp314-cp314-macosx_10_12_x86_64.whl:

Publisher: release.yml on hiop-oss/rsonschema

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rsonschema-0.1.16-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for rsonschema-0.1.16-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f569e9de6e5c109fd31085be937fdfcc5748c4c7459b09fe09c8154eace24b44
MD5 8d8d9b3a4e727d0c5b58d96f920c05be
BLAKE2b-256 80905a6ced5fde24c89695b8fde7c8403873c0804af8bef7bc811e7df49f4c9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for rsonschema-0.1.16-cp312-cp312-win_amd64.whl:

Publisher: release.yml on hiop-oss/rsonschema

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rsonschema-0.1.16-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rsonschema-0.1.16-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8b22af99790cfc39e6ec6f167fe7343408bede05c1a0f1496fe4ad9bd6697fc9
MD5 42253bb5826133ac4aafb6e7641048b8
BLAKE2b-256 f32d86abbb576ec656dfcc63ce3df8a0d0ddf92587dab8993a4314e14f4ad490

See more details on using hashes here.

Provenance

The following attestation bundles were made for rsonschema-0.1.16-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on hiop-oss/rsonschema

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page