bilal-fazlani / circe-json-schema   0.4.3

Apache License 2.0 GitHub

JSON Schema validation for Circe

Scala versions: 3.x 2.13

circe-json-schema

Build Coverage status Gitter Maven Central

This project provides some basic tools for performing JSON Schema validation with Circe.

The current version of the library is a wrapper for the Everit JSON Schema Validator, although it does not expose any org.everit or org.json types in its public API. Future releases will drop the Everit dependency, although we don't currently have an exact timeline for when this will happen.

The library only supports Draft 7 of the JSON Schema specification.

We are currently testing against the non-ref cases provided in the JSON Schema Test Suite.

Setup

Note that this library currently depends on the most recent version of the Everit validator, which is not published to Maven Central. You'll need to add the Jitpack resolver to your build:

resolvers += "jitpack".at("https://jitpack.io")

See the Everit documentation for the equivalent Maven configuration.

Once you've configured the resolver, you can add this project to your dependencies:

libraryDependencies += "io.circe" %% "circe-json-schema" % "0.1.0"

And the appropriate Everit version will be pulled in transitively.

Usage

The io.circe.schema package contains just two types (Schema and ValidationError), each of which has just a few methods. You can load a schema from either a Json value or a string.

import io.circe.literal._
import io.circe.schema.Schema

val polygonSchema: Schema = Schema.load(
  json"""
    {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "Polygon"
        },
        "coordinates": {
          "type": "array",
          "items": {
            "type": "array",
            "minItems": 2,
            "maxItems": 3
          }
        }
      }
    }
  """
)

The validate method on Schema instances returns either nothing (as Valid(())) or a non-empty list of validation errors, so if we have some values like this:

val good = json"""{"type": "Polygon", "coordinates": [[0, 0], [1, 0], [1, 1], [0, 1]] }"""
val bad1 = json"""true"""
val bad2 = json"""{"type": "Shape", "coordinates": [[0, 0], [1, 0], [1, 1], [0, 1]] }"""
val bad3 = json"""{"type": "Polygon", "coordinates": [[0], [1, 0], [1, 2, 3, 4], [0, 1]] }"""
val bad4 = json"""{"type": "Polygon", "coordinates": [1, 0] }"""

The results look like this:

scala> polygonSchema.validate(good)
res0: cats.data.ValidatedNel[io.circe.schema.ValidationError,Unit] = Valid(())

scala> polygonSchema.validate(bad1).swap.map(_.toList).toList.flatten.map(_.getMessage).foreach(println)
#: expected type: JSONObject, found: Boolean

scala> polygonSchema.validate(bad2).swap.map(_.toList).toList.flatten.map(_.getMessage).foreach(println)
#/type: #: only 1 subschema matches out of 2
#/type:

scala> polygonSchema.validate(bad3).swap.map(_.toList).toList.flatten.map(_.getMessage).foreach(println)
#/coordinates: 2 schema violations found
#/coordinates/0: expected minimum item count: 2, found: 1
#/coordinates/2: expected maximum item count: 3, found: 4

scala> polygonSchema.validate(bad4).swap.map(_.toList).toList.flatten.map(_.getMessage).foreach(println)
#/coordinates: 2 schema violations found
#/coordinates/0: expected type: JSONArray, found: Integer
#/coordinates/1: expected type: JSONArray, found: Integer

The details of these errors and the error messages are subject to change.

Contributors and participation

This project supports the Scala code of conduct and we want all of its channels (Gitter, GitHub, etc.) to be welcoming environments for everyone.

Please see the Circe contributors' guide for details on how to submit a pull request.

License

circe-json-schema is licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.