Skip to content
Snippets Groups Projects
David John's avatar
David John authored
Resolve "Release v0.2.0"

Closes #6

See merge request !6
95c44cd2

Schema Police

This library provides the [SchemaInspector] type which simplifies building a JSON validator from the schemas present in the OpenAPI spec (tested on OpenAPI spec 3.0.3 wich uses the Json Schema draft 202012).

The primary goal of this libary is to provide the necessary glue to make it possible to use the OpenAPI spec generated by the utoipa crate with the jsonschema schema validation library. However, this approach may become unnessary if local references start to get resolved correctly in the jsonschema crate (which currently results in a invalid reference error).

Why the name Schema Police?

It's a reference to the Radiohead song 'Karma Police'

Usage Example

use schema_police::SchemaInspector;
use utoipa::OpenApi;

fn main() {
    // Get the schemas from OpenAPI spec generated by utoipa
    let schemas = serde_json::to_value(ApiDoc::openapi().components.unwrap().schemas).unwrap();
    // Initialize JSON inspector  for the `ExampleSchema` type
    let inspector = SchemaInspector::new_infer::<ExampleSchema>(&schemas, false).unwrap();
    // Example JSON request that contains errors
    let example_request = serde_json::json!({
        "integer": 10,
        "string": "hello",
        "array": ["one"]
    });

    let Err(result) = inspector.inspect(&example_request) else {
        panic!("This should be an error!");
    };

    let context = result.context();
    assert_eq!(context[0].description, r#"["one"] has less than 2 items"#);
    assert_eq!(context[1].description, "10 is less than the minimum of 15");
    assert_eq!(
        result.to_string(),
        r#"JSON doesn't match expected schema: found 2 errors"#
    );
}

#[derive(utoipa::OpenApi)]
#[openapi(components(schemas(ExampleSchema)))]
struct ApiDoc;

#[allow(unused)]
#[derive(utoipa::ToSchema)]
struct ExampleSchema {
    #[schema(minimum = 15, maximum = 90)]
    integer: i32,
    #[schema(pattern = "^hello.*")]
    string: String,
    #[schema(min_items = 2)]
    array: Vec<String>,
}