A JSON Schema validator implementation. It compiles schema into a validation tree to have validation as fast as possible.
Supported drafts:
idn-hostname.json
test case)bignum.json
test case)Partially supported drafts (some keywords are not implemented):
- Draft 2019-09 (requires the draft201909
feature enabled)
- Draft 2020-12 (requires the draft202012
feature enabled)
```toml
jsonschema = "0.16" ```
To validate documents against some schema and get validation errors (if any):
```rust use jsonschema::JSONSchema; use serde_json::json;
fn main() { let schema = json!({"maxLength": 5}); let instance = json!("foo"); let compiled = JSONSchema::compile(&schema) .expect("A valid schema"); let result = compiled.validate(&instance); if let Err(errors) = result { for error in errors { println!("Validation error: {}", error); println!( "Instance path: {}", error.instance_path ); } } } ```
Each error has an instance_path
attribute that indicates the path to the erroneous part within the validated instance.
It could be transformed to JSON Pointer via .to_string()
or to Vec<String>
via .into_vec()
.
If you only need to know whether document is valid or not (which is faster):
```rust use jsonschema::isvalid; use serdejson::json;
fn main() { let schema = json!({"maxLength": 5}); let instance = json!("foo"); assert!(is_valid(&schema, &instance)); } ```
Or use a compiled schema (preferred):
```rust use jsonschema::JSONSchema; use serde_json::json;
fn main() { let schema = json!({"maxLength": 5}); let instance = json!("foo"); // Draft is detected automatically // with fallback to Draft7 let compiled = JSONSchema::compile(&schema) .expect("A valid schema"); assert!(compiled.is_valid(&instance)); } ```
jsonschema
supports basic
& flag
output styles from Draft 2019-09, so you can serialize the validation results with serde
:
```rust use jsonschema::{Output, BasicOutput, JSONSchema}; use serde_json::json;
fn main() { let schemajson = json!({ "title": "string value", "type": "string" }); let instance = json!("some string"); let schema = JSONSchema::compile(&schemajson) .expect("A valid schema");
let output: BasicOutput = schema.apply(&instance).basic();
let output_json = serde_json::to_value(output)
.expect("Failed to serialize output");
assert_eq!(
output_json,
json!({
"valid": true,
"annotations": [
{
"keywordLocation": "",
"instanceLocation": "",
"annotations": {
"title": "string value"
}
}
]
})
);
} ```
By default, jsonschema
resolves HTTP references via reqwest
without TLS support.
If you'd like to resolve HTTPS, you need to enable TLS support in reqwest
:
toml
reqwest = { version = "*", features = [ "rustls-tls" ] }
Otherwise, you might get validation errors like invalid URL, scheme is not http
.
This library is functional and ready for use, but its API is still evolving to the 1.0 API.
./bindings/python
directoryThere is a comparison with other JSON Schema validators written in Rust - jsonschema_valid==0.4.0
and valico==3.6.0
.
Test machine i8700K (12 cores), 32GB RAM.
Input values and schemas:
zuora.json
). Validated against OpenAPI 3.0 JSON Schema (openapi.json
).kubernetes.json
). Validated against Swagger JSON Schema (swagger.json
).canada.json
). Schema is taken from the GeoJSON website (geojson.json
).citm_catalog.json
). Schema is inferred via infers-jsonschema & manually adjusted (citm_catalog_schema.json
).Fast
is taken from fastjsonschema benchmarks (fast_schema.json
, fast_valid.json
and fast_invalid.json
).| Case | Schema size | Instance size | | -------------- | ----------- | ------------- | | OpenAPI | 18 KB | 4.5 MB | | Swagger | 25 KB | 3.0 MB | | Canada | 4.8 KB | 2.1 MB | | CITM catalog | 2.3 KB | 501 KB | | Fast (valid) | 595 B | 55 B | | Fast (invalid) | 595 B | 60 B |
Here is the average time for each contender to validate. Ratios are given against compiled JSONSchema
using its validate
method. The is_valid
method is faster, but gives only a boolean return value:
| Case | jsonschemavalid | valico | jsonschema (validate) | jsonschema (isvalid) | | -------------- | ----------------------- | ----------------------- | --------------------- | ---------------------- | | OpenAPI | - (1) | - (1) | 4.717 ms | 4.279 ms (x0.90) | | Swagger | - (2) | 83.357 ms (x12.47) | 6.681 ms | 4.533 ms (x0.67) | | Canada | 32.987 ms (x31.38) | 141.41 ms (x134.54) | 1.051 ms | 1.046 ms (x0.99) | | CITM catalog | 4.735 ms (x2.00) | 13.222 ms (x5.58) | 2.367 ms | 535.07 us (x0.22) | | Fast (valid) | 2.00 us (x3.85) | 3.18 us (x6.13) | 518.39 ns | 97.91 ns (x0.18) | | Fast (invalid) | 339.28 ns (x0.50) | 3.34 us (x5.00) | 667.55 ns | 5.41ns (x0.01) |
Notes:
jsonschema_valid
and valico
do not handle valid path instances matching the ^\\/
regex.
jsonschema_valid
fails to resolve local references (e.g. #/definitions/definitions
).
You can find benchmark code in benches/jsonschema.rs
, Rust version is 1.57
.
If you have anything to discuss regarding this library, please, join our gitter!