json_schema_dart2 3.0.0

JSON Schema (Forked) #

A platform agnostic (dart:html or dart:io) Dart library for validating JSON instances against JSON Schemas (multi-version support with latest of Draft 6).

Forked changes #

  • Does not support dart < 2.0.0
  • Supports dart 2.0.0
  • Uses uri instead of uri_template
  • Package name changed to json_schema_dart2 (to allow publishing on pub)

Build Status

How To Create and Validate Against a Schema #

Synchronous Creation - Self Contained #

The simplest way to create a schema is to pass JSON data directly to JsonSchema.createSchema with a JSON String, or decoded JSON via Dart Map or bool.

After creating any schema, JSON instances can be validated by calling .validate(instance) on that schema. By default, instances are expected to be pre-parsed JSON as native dart primitives (Map, List, String, bool, num, int). You can also optionally parse at validation time by passing in a string and setting parseJson: schema.validate('{ "name": "any JSON object"}', parseJson: true).

Note: Creating JsonSchemas synchronously implies access to all $refs within the root schema. If you don't have access to all this data at the time of the construction, see "Asynchronous Creation" examples below.

Example #

A schema can be created with a Map that is either hand-crafted, referenced from a JSON file, or previously fetched from the network or file system.

import 'package:json_schema_dart2/json_schema.dart';

main() {
  /// Define schema in a Dart [Map] or use a JSON [String].
  final mustBeIntegerSchemaMap = {"type": "integer"};

  // Create some examples to validate against the schema.
  final n = 3;
  final decimals = 3.14;
  final str = 'hi';

  // Construct the schema from the schema map or JSON string.
  final schema = JsonSchema.createSchema(mustBeIntegerSchemaMap);

  print('$n => ${schema.validate(n)}'); // true
  print('$decimals => ${schema.validate(decimals)}'); // false
  print('$str => ${schema.validate(str)}'); // false
}

Synchronous Creation, Local Ref Cache #

If you want to create JsonSchemas synchronously, and you have $refs that cannot be resolved within the root schema, but you have a cache of those $ref'd schemas locally, you can write a RefProvider to get them during schema evaluation.

Example #

import 'package:json_schema_dart2/json_schema.dart';
import 'package:dart2_constant/convert.dart';

main() {
  final referencedSchema = {
    r"$id": "https://example.com/geographical-location.schema.json",
    r"$schema": "http://json-schema.org/draft-06/schema#",
    "title": "Longitude and Latitude",
    "description": "A geographical coordinate on a planet (most commonly Earth).",
    "required": ["latitude", "longitude"],
    "type": "object",
    "properties": {
      "name": {"type": "string"},
      "latitude": {"type": "number", "minimum": -90, "maximum": 90},
      "longitude": {"type": "number", "minimum": -180, "maximum": 180}
    }
  };

  final RefProvider refProvider = (String ref) {
    final Map references = {
      'https://example.com/geographical-location.schema.json': JsonSchema.createSchema(referencedSchema),
    };

    if (references.containsKey(ref)) {
      return references[ref];
    }

    return null;
  };

  final schema = JsonSchema.createSchema({
    'type': 'array',
    'items': {r'$ref': 'https://example.com/geographical-location.schema.json'}
  }, refProvider: refProvider);

  final workivaLocations = [
    {
      'name': 'Ames',
      'latitude': 41.9956731,
      'longitude': -93.6403663,
    },
    {
      'name': 'Scottsdale',
      'latitude': 33.4634707,
      'longitude': -111.9266617,
    }
  ];

  final badLocations = [
    {
      'name': 'Bad Badlands',
      'latitude': 181,
      'longitude': 92,
    },
    {
      'name': 'Nowhereville',
      'latitude': -2000,
      'longitude': 7836,
    }
  ];

  print('${json.encode(workivaLocations)} => ${schema.validate(workivaLocations)}');
  print('${json.encode(badLocations)} => ${schema.validate(badLocations)}');
}

Asynchronous Creation, Remote HTTP Refs #

If you have schemas that have nested $refs that are HTTP URIs that are publicly accessible, you can use Future<JsonSchema> JsonSchema.createSchemaAsync and the references will be fetched as needed during evaluation. You can also use JsonSchema.createSchemaFromUrl if you want to fetch the root schema remotely as well (see next example).

Example #

import 'dart:io';

import 'package:json_schema_dart2/json_schema.dart';

// For VM:
import 'package:json_schema_dart2/vm.dart';

// For Browser:
// import 'package:json_schema_dart2/browser.dart';

main() async {
  // For VM:
  configureJsonSchemaForVm();

  // For Browser:
  // configureJsonSchemaForBrowser();

  // Schema Defined as a JSON String
  final schema = await JsonSchema.createSchemaAsync(r'''
  {
    "type": "array",
    "items": {
      "$ref": "https://raw.githubusercontent.com/json-schema-org/JSON-Schema-Test-Suite/master/remotes/integer.json"
    }
  }
  ''');

  // Create some examples to validate against the schema.
  final numbersArray = [1, 2, 3];
  final decimalsArray = [3.14, 1.2, 5.8];
  final strArray = ['hello', 'world'];

  print('$numbersArray => ${schema.validate(numbersArray)}'); // true
  print('$decimalsArray => ${schema.validate(decimalsArray)}'); // false
  print('$strArray => ${schema.validate(strArray)}'); // false

  // Exit the process cleanly (VM Only).
  exit(0);
}

Asynchronous Creation, From URL or File #

You can also create a schema directly from a publicly accessible URL, like so:

Example 1 - URL #

import 'dart:io';

import 'package:json_schema_dart2/json_schema.dart';

// For VM:
import 'package:json_schema_dart2/vm.dart';

// For Browser:
// import 'package:json_schema_dart2/browser.dart';

main() async {
  // For VM:
  configureJsonSchemaForVm();

  // For Browser:
  // configureJsonSchemaForBrowser();

  final url = "https://raw.githubusercontent.com/json-schema-org/JSON-Schema-Test-Suite/master/remotes/integer.json";

  final schema = await JsonSchema.createSchemaFromUrl(url);

  // Create some examples to validate against the schema.
  final n = 3;
  final decimals = 3.14;
  final str = 'hi';

  print('$n => ${schema.validate(n)}'); // true
  print('$decimals => ${schema.validate(decimals)}'); // false
  print('$str => ${schema.validate(str)}'); // false

  // Exit the process cleanly (VM Only).
  exit(0);
}

Example 2 - File #

import 'dart:io';

import 'package:json_schema_dart2/json_schema.dart';

// For VM:
import 'package:json_schema_dart2/vm.dart';

// For Browser:
// import 'package:json_schema_dart2/browser.dart';

main() async {
  // For VM:
  configureJsonSchemaForVm();

  // For Browser:
  // configureJsonSchemaForBrowser();

  final file = "example/readme/asynchronous_creation/geo.schema.json";

  final schema = await JsonSchema.createSchemaFromUrl(file);

  // Create some examples to validate against the schema.
  final workivaAmes = {
    'latitude': 41.9956731,
    'longitude': -93.6403663,
  };

  final nowhereville = {
    'latitude': -2000,
    'longitude': 7836,
  };

  print('$workivaAmes => ${schema.validate(workivaAmes)}'); // true
  print('$nowhereville => ${schema.validate(nowhereville)}'); // false

  // Exit the process cleanly (VM Only).
  exit(0);
}

Asynchronous Creation, with custom remote $refs: #

If you have nested $refs that are either non-HTTP URIs or non-publicly-accessible HTTP $refs, you can supply an RefProviderAsync to createSchemaAsync, and perform any custom logic you need.

Example #

import 'dart:io';
import 'dart:async';
import 'package:dart2_constant/convert.dart';

import 'package:json_schema_dart2/json_schema.dart';

// For VM:
import 'package:json_schema_dart2/vm.dart';

// For Browser:
// import 'package:json_schema_dart2/browser.dart';

main() async {
  // For VM:
  configureJsonSchemaForVm();

  // For Browser:
  // configureJsonSchemaForBrowser();

  final referencedSchema = {
    r"$id": "https://example.com/geographical-location.schema.json",
    r"$schema": "http://json-schema.org/draft-06/schema#",
    "title": "Longitude and Latitude",
    "description": "A geographical coordinate on a planet (most commonly Earth).",
    "required": ["latitude", "longitude"],
    "type": "object",
    "properties": {
      "name": {"type": "string"},
      "latitude": {"type": "number", "minimum": -90, "maximum": 90},
      "longitude": {"type": "number", "minimum": -180, "maximum": 180}
    }
  };

  final RefProviderAsync refProvider = (String ref) async {
    final Map references = {
      'https://example.com/geographical-location.schema.json': JsonSchema.createSchema(referencedSchema),
    };

    if (references.containsKey(ref)) {
      // Silly example that adds a 1 second delay.
      // In practice, you could make any service call here,
      // parse the results into a schema, and return.
      await new Future.delayed(new Duration(seconds: 1));
      return references[ref];
    }

    // Fall back to default URL $ref behavior
    return await JsonSchema.createSchemaFromUrl(ref);
  };

  final schema = await JsonSchema.createSchemaAsync({
    'type': 'array',
    'items': {r'$ref': 'https://example.com/geographical-location.schema.json'}
  }, refProvider: refProvider);

  final workivaLocations = [
    {
      'name': 'Ames',
      'latitude': 41.9956731,
      'longitude': -93.6403663,
    },
    {
      'name': 'Scottsdale',
      'latitude': 33.4634707,
      'longitude': -111.9266617,
    }
  ];

  final badLocations = [
    {
      'name': 'Bad Badlands',
      'latitude': 181,
      'longitude': 92,
    },
    {
      'name': 'Nowhereville',
      'latitude': -2000,
      'longitude': 7836,
    }
  ];

  print('${json.encode(workivaLocations)} => ${schema.validate(workivaLocations)}');
  print('${json.encode(badLocations)} => ${schema.validate(badLocations)}');

  exit(0);
}

How To Use Schema Information #

Schema information can be used for validation; but it can also be a valuable source of information about the structure of data. The JsonSchema class fully parses the schema first, which itself must be valid on all paths within the schema. Accessors are provided for all specified keywords of the JSON Schema specification associated with a schema, so tools can use it to create rich views of the data, like forms or diagrams.

One example use is the deprecated schemadot program included in the bin folder which takes schema as input and outputs a Graphviz dot file, providing a picture of the schema. This does not provide all information of the schema, and is a work in progress - but it can be useful to see what a schema is.

For example, the grades_schema.json is:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title" : "Grade Tracker",
    "type" : "object",
    "additionalProperties" : false,
    "properties" : {
	"semesters" : {
	    "type" : "array",
	    "items" : {
                "type" : "object",
                "additionalProperties" : false,
                "properties" : {
                    "semester": { "type" : "integer" },
                    "grades" : {
                        "type" : "array",
                        "items" : {
                            "type" : "object",
                            "additionalProperties" : false,
                            "required" : [ "date", "type", "grade", "std" ],
                            "properties" : {
                                "date" : { "type" : "string"},
                                "type" : { "enum" : [ "homework", "quiz", "test", "final_exam" ] },
                                "grade" : { "type" : "number"},
                                "std" : { 
                                    "oneOf" : [ 
                                        {"type" : "number"}, 
                                        {"type" : "null"}
                                    ] 
                                },
                                "avg" : { 
                                    "oneOf" : [ 
                                        {"type" : "number"}, 
                                        {"type" : "null"}
                                    ] 
                                }
                            }
                        }
                    }
                }
            }
  	    }
    }
}

And the generated image is:

Grades!

For more detailed image open link: Grade example schema diagram

3.0.0 #

  • Does not support dart < 2.0.0
  • Supports dart 2.0.0
  • Uses uri instead of uri_template
  • Package name changed to json_schema_dart2 (to allow publishing on pub)

2.0.0 #

  • json_schema is no longer bound to dart:io and works in the browser!
  • Full JSON Schema draft6 compatibility
  • Much better $ref resolution, including deep nesting of $refs
  • More typed keyword getters for draft6 like examples
  • Syncronous schema evaluation by default
  • Optional async evaluation and fetching with createSchemaAsync
  • Automatic parsing of JSON strings passed to createSchema and createSchemaAsync
  • Ability to do custom resolution of $refs with RefProvider and RefProviderAsync
  • Optional parsing of JSON strings passed to validate with parseJson = true
  • Dart 2.0 compatibility
  • Many small changes to make things more in line with modern dart.
  • Please see the migration guide for additional info.

1.0.8 #

  • Code cleanup
  • Strong mode
  • Switch build tools to dart_dev

1.0.7 #

  • Update dependency constraint on the args package.

1.0.3 #

  • Add a dependency on the args package.

1.0.2 #

  • Add a dependency on the logging package.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  json_schema_dart2: ^3.0.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:json_schema_dart2/browser.dart';
import 'package:json_schema_dart2/json_schema.dart';
import 'package:json_schema_dart2/schema_dot.dart';
import 'package:json_schema_dart2/vm.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
26
Health:
Code health derived from static analysis. [more]
78
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
57
Learn more about scoring.

We analyzed this package on Jul 18, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.4.0
  • pana: 0.12.19

Platforms

Detected platforms: web

Platform components identified in package: html, io, js.

Health suggestions

Fix lib/schema_dot.dart. (-10.44 points)

Analysis of lib/schema_dot.dart reported 22 hints, including:

line 59 col 7: Use isNotEmpty instead of length

line 60 col 7: Use isNotEmpty instead of length

line 61 col 7: Use isNotEmpty instead of length

line 62 col 7: Use isNotEmpty instead of length

line 63 col 7: Use isNotEmpty instead of length

Fix lib/src/json_schema/validator.dart. (-4.89 points)

Analysis of lib/src/json_schema/validator.dart reported 10 hints, including:

line 82 col 12: Use isEmpty instead of length

line 149 col 29: Use isNotEmpty instead of length

line 164 col 9: Use isNotEmpty instead of length

line 302 col 13: DO use curly braces for all flow control structures.

line 313 col 13: DO use curly braces for all flow control structures.

Fix bin/schemadot.dart. (-2.96 points)

Analysis of bin/schemadot.dart reported 6 hints, including:

line 91 col 61: 'allowMultiple' is deprecated and shouldn't be used.

line 92 col 63: 'allowMultiple' is deprecated and shouldn't be used.

line 101 col 9: 'allowMultiple' is deprecated and shouldn't be used.

line 137 col 5: Use rethrow to rethrow a caught exception.

line 141 col 7: The top level variable '_logger' isn't used.

Fix additional 14 files with analysis or formatting issues. (-5.46 points)

Additional issues in the following files:

  • lib/src/json_schema/json_schema.dart (6 hints)
  • bin/gensamples.dart (2 hints)
  • lib/src/json_schema/type_validators.dart (2 hints)
  • lib/src/json_schema/vm/platform_functions.dart (1 hint)
  • lib/browser.dart (Run dartfmt to format lib/browser.dart.)
  • lib/json_schema.dart (Run dartfmt to format lib/json_schema.dart.)
  • lib/src/json_schema/browser/platform_functions.dart (Run dartfmt to format lib/src/json_schema/browser/platform_functions.dart.)
  • lib/src/json_schema/constants.dart (Run dartfmt to format lib/src/json_schema/constants.dart.)
  • lib/src/json_schema/format_exceptions.dart (Run dartfmt to format lib/src/json_schema/format_exceptions.dart.)
  • lib/src/json_schema/global_platform_functions.dart (Run dartfmt to format lib/src/json_schema/global_platform_functions.dart.)
  • lib/src/json_schema/schema_type.dart (Run dartfmt to format lib/src/json_schema/schema_type.dart.)
  • lib/src/json_schema/typedefs.dart (Run dartfmt to format lib/src/json_schema/typedefs.dart.)
  • lib/src/json_schema/utils.dart (Run dartfmt to format lib/src/json_schema/utils.dart.)
  • lib/vm.dart (Run dartfmt to format lib/vm.dart.)

Maintenance suggestions

Maintain an example.

None of the files in the package's example/ directory matches known example patterns.

Common filename patterns include main.dart, example.dart, and json_schema_dart2.dart. Packages with multiple examples should provide example/README.md.

For more information see the pub package layout conventions.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
args >=0.11.0 <2.0.0 1.5.2
dart2_constant ^1.0.0 1.0.2+dart2
logging >=0.9.3 <0.12.0 0.11.3+2
path ^1.3.0 1.6.2
uri ^0.11.0 0.11.3+1
w_transport ^3.1.2 3.2.8
Transitive dependencies
async 2.3.0
charcode 1.1.2
cli_repl 0.2.0+1
collection 1.14.11
colorize 2.0.0
fluri 1.2.5
glob 1.1.7
http 0.12.0+2
http_parser 3.1.3
intl 0.15.8
js 0.6.1+1
matcher 0.12.5
meta 1.1.7
mime 0.9.6+3
package_config 1.0.5
package_resolver 1.0.10
pedantic 1.8.0+1
quiver 2.0.3
sass 1.22.7
sockjs_client 0.3.5
sockjs_client_wrapper 1.0.8
source_maps 0.10.8
source_span 1.5.5
stack_trace 1.9.3
stream_transform 0.0.19
string_scanner 1.0.4
term_glyph 1.1.0
tuple 1.0.2
typed_data 1.1.6
utf 0.9.0+5
w_common 1.20.0
watcher 0.9.7+12
Dev dependencies
coverage >=0.7.6
dart_dev any
dart_style any
dependency_validator ^1.0.0
shelf ^0.7.2
shelf_static ^0.2.7
test ^1.5.0

Admin