rsonschema
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:
jsonschema::error::ValidationErrorborrows theinstanceattribute, adding complexity.- 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:
Here's how you can start using rsonschema in your Rust project:
let schema = json!;
let instance = json!;
let report = validate;
assert!;
let instance = json!;
let report = validate;
assert_eq!;
Python
Install from PyPI (requires Python >= 3.10):
=
# validate(instance, schema, pointer=None, ref_resolver=None)
=
assert ==
=
assert == 1
assert # 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 = json!;
let report = validate;
let error = report.errors.unwrap.into_iter.min.unwrap;
println!;
// "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 = json!;
let report = validate;
let error = report.errors.unwrap.into_iter.min.unwrap;
println!;
// {"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 = json!;
let report = validate;
let error = report.errors.unwrap.into_iter.min.unwrap;
println!;
// "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:
=
=
# {"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
$dynamicAnchorand$dynamicRefare 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.