jsonschema-rs/README.md

171 lines
6.9 KiB
Markdown
Raw Normal View History

2020-03-04 14:07:40 +00:00
# jsonschema
2020-05-14 12:57:14 +00:00
[![ci](https://github.com/Stranger6667/jsonschema-rs/workflows/ci/badge.svg)](https://github.com/Stranger6667/jsonschema-rs/actions)
2020-05-14 10:22:55 +00:00
[![codecov](https://codecov.io/gh/Stranger6667/jsonschema-rs/branch/master/graph/badge.svg)](https://codecov.io/gh/Stranger6667/jsonschema-rs)
2020-05-14 12:57:14 +00:00
[![Crates.io](https://img.shields.io/crates/v/jsonschema.svg)](https://crates.io/crates/jsonschema)
2021-06-17 11:07:41 +00:00
[![docs.rs](https://docs.rs/jsonschema/badge.svg)](https://docs.rs/jsonschema/)
2020-08-30 13:03:06 +00:00
[![gitter](https://img.shields.io/gitter/room/Stranger6667/jsonschema-rs.svg)](https://gitter.im/Stranger6667/jsonschema-rs)
2020-05-14 10:22:55 +00:00
2020-04-15 15:02:29 +00:00
A JSON Schema validator implementation. It compiles schema into a validation tree to have validation as fast as possible.
Supported drafts:
2020-06-29 18:18:57 +00:00
- Draft 7 (except optional `idn-hostname.json` test case)
- Draft 6
- Draft 4 (except optional `bignum.json` test case)
2020-04-15 15:02:29 +00:00
```toml
# Cargo.toml
jsonschema = "0.12"
2020-04-15 15:02:29 +00:00
```
2020-03-04 14:07:40 +00:00
2020-03-28 22:49:23 +00:00
To validate documents against some schema and get validation errors (if any):
2020-03-04 14:07:40 +00:00
```rust
use jsonschema::{Draft, JSONSchema};
2020-03-04 14:07:40 +00:00
use serde_json::json;
fn main() {
2020-03-04 14:07:40 +00:00
let schema = json!({"maxLength": 5});
let instance = json!("foo");
let compiled = JSONSchema::compile(&schema)
.expect("A valid schema");
2020-03-04 14:07:40 +00:00
let result = compiled.validate(&instance);
2020-03-28 22:49:23 +00:00
if let Err(errors) = result {
for error in errors {
println!("Validation error: {}", error);
2021-05-07 06:49:51 +00:00
println!(
"Instance path: {}", error.instance_path
);
2020-06-29 18:18:57 +00:00
}
2020-03-28 22:49:23 +00:00
}
2020-03-04 14:07:40 +00:00
}
2020-06-29 18:18:57 +00:00
```
2020-03-04 14:07:40 +00:00
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()`.
2020-03-29 08:50:28 +00:00
If you only need to know whether document is valid or not (which is faster):
2020-03-28 22:49:23 +00:00
```rust
use jsonschema::is_valid;
use serde_json::json;
fn main() {
let schema = json!({"maxLength": 5});
let instance = json!("foo");
assert!(is_valid(&schema, &instance));
}
2020-03-29 08:50:28 +00:00
```
Or use a compiled schema (preferred):
```rust
use jsonschema::{Draft, JSONSchema};
2020-03-29 08:50:28 +00:00
use serde_json::json;
fn main() {
2020-03-29 08:50:28 +00:00
let schema = json!({"maxLength": 5});
let instance = json!("foo");
2021-02-04 10:47:04 +00:00
// Draft is detected automatically
// with fallback to Draft7
let compiled = JSONSchema::compile(&schema)
.expect("A valid schema");
2020-03-29 08:50:28 +00:00
assert!(compiled.is_valid(&instance));
}
```
2020-03-28 22:49:23 +00:00
## Output styles
`jsonschema` supports `basic` & `flag` output styles from Draft 2019-09, so you can serialize the validation results with `serde`:
```rust
use jsonschema::{Draft, Output, BasicOutput, JSONSchema};
fn main() {
let schema_json = serde_json::json!({
"title": "string value",
"type": "string"
});
let instance = serde_json::json!{"some string"};
let schema = JSONSchema::options()
.compile(&schema_json)
.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,
serde_json::json!({
"valid": true,
"annotations": [
{
"keywordLocation": "",
"instanceLocation": "",
"annotations": {
"title": "string value"
}
}
]
})
);
}
```
2021-08-15 16:19:03 +00:00
## Status
This library is functional and ready for use, but its API is still evolving to the 1.0 API.
2021-01-01 12:23:21 +00:00
## Bindings
2021-02-04 10:47:04 +00:00
- Python - See the `./bindings/python` directory
2021-01-01 12:23:21 +00:00
- Ruby - a [crate](https://github.com/driv3r/rusty_json_schema) by @driv3r
2020-04-15 15:02:29 +00:00
## Performance
2021-05-01 19:33:52 +00:00
There is a comparison with other JSON Schema validators written in Rust - `jsonschema_valid==0.4.0` and `valico==3.6.0`.
2020-04-15 15:02:29 +00:00
Test machine i8700K (12 cores), 32GB RAM.
2021-05-02 10:48:16 +00:00
Input values and schemas:
2020-04-15 15:02:29 +00:00
2021-05-02 10:48:16 +00:00
- [Zuora](https://github.com/APIs-guru/openapi-directory/blob/master/APIs/zuora.com/2021-04-23/openapi.yaml) OpenAPI schema (`zuora.json`). Validated against [OpenAPI 3.0 JSON Schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.0/schema.json) (`openapi.json`).
- [Kubernetes](https://raw.githubusercontent.com/APIs-guru/openapi-directory/master/APIs/kubernetes.io/v1.10.0/swagger.yaml) Swagger schema (`kubernetes.json`). Validated against [Swagger JSON Schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v2.0/schema.json) (`swagger.json`).
- Canadian border in GeoJSON format (`canada.json`). Schema is taken from the [GeoJSON website](https://geojson.org/schema/FeatureCollection.json) (`geojson.json`).
- Concert data catalog (`citm_catalog.json`). Schema is inferred via [infers-jsonschema](https://github.com/Stranger6667/infers-jsonschema) & manually adjusted (`citm_catalog_schema.json`).
- `Fast` is taken from [fastjsonschema benchmarks](https://github.com/horejsek/python-fastjsonschema/blob/master/performance.py#L15) (`fast_schema.json`, `fast_valid.json` and `fast_invalid.json`).
2020-04-15 15:02:29 +00:00
2021-05-02 10:48:16 +00:00
| 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 |
2020-06-08 20:50:54 +00:00
2021-05-02 10:48:16 +00:00
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:
2021-02-03 10:35:34 +00:00
2021-05-02 10:48:16 +00:00
| Case | jsonschema_valid | valico | jsonschema (validate) | jsonschema (is_valid) |
| -------------- | ----------------------- | ----------------------- | --------------------- | ---------------------- |
2021-05-07 06:49:51 +00:00
| OpenAPI | - (1) | - (1) | 1.704 ms | 1.651 ms (**x0.96**) |
| Swagger | - (2) | 97.401 ms (**x18.37**) | 5.234 ms | 3.507 ms (**x0.66**) |
2021-05-02 10:48:16 +00:00
| Canada | 45.555 ms (**x39.20**) | 164.12 ms (**x141.23**) | 1.162 ms | 1.165 ms (**x1.00**) |
| CITM catalog | 6.107 ms (**x2.28**) | 15.233 ms (**x5.69**) | 2.677 ms | 755.58 us (**x0.28**) |
| Fast (valid) | 2.04 us (**x5.67**) | 3.70 us (**x10.28**) | 359.59 ns | 93.40 ns (**x0.25**) |
| Fast (invalid) | 397.52 ns (**x0.81**) | 3.78 us (**x7.75**) | 487.25 ns | 5.15 ns (**x0.01**) |
2020-06-08 20:50:54 +00:00
2021-05-02 10:48:16 +00:00
Notes:
2021-05-07 06:49:51 +00:00
1. `jsonschema_valid` and `valico` do not handle valid path instances matching the `^\\/` regex.
2021-05-02 10:48:16 +00:00
2021-05-07 06:49:51 +00:00
2. `jsonschema_valid` fails to resolve local references (e.g. `#/definitions/definitions`).
2021-05-02 10:48:16 +00:00
You can find benchmark code in `benches/jsonschema.rs`, Rust version is `1.51`.
2020-04-15 15:02:29 +00:00
2020-08-30 13:03:06 +00:00
## Support
If you have anything to discuss regarding this library, please, join our [gitter](https://gitter.im/Stranger6667/jsonschema-rs)!