jsonschema
Version, currently main branch1 version
- main branchlatestJul 19, 2022
github.com/aarongodin/jsonschema
Comprehensive json-schema validation and generator
7 stars
0 dependents
License: MIT
Installation
# Add this to your shard.yml
dependencies:
jsonschema:
github: aarongodin/jsonschema
branch: mainmain is a branch, not a release, so this tracks it rather than pinning a version.
Then run:
shards installshard.yml
- Crystal
>= 1.3.1- License
- MIT
- Author
- Aaron Godin <godinaaweb@gmail.com>
Dependencies
Runtime Dependencies
- validator*github: nicolab/crystal-validator
README
[](https://github.com/aarongodin/jsonschema/releases)
[](https://github.com/aarongodin/jsonschema/actions/workflows/crystal.yml)

# jsonschema
Comprehensive [JSON Schema](https://json-schema.org/) validation and generator for Crystal. Read below for a high-level description of the API, or check out the [API Docs](https://aarongodin.github.io/jsonschema/) for full details.
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
jsonschema:
github: aarongodin/jsonschema
```
2. Run `shards install`
## Overview
* Read JSON files from your file system **at compile time** and generate Crystal code to convert a JSON Schema document to a `JSONSchema::Validator` object.
* Create `JSONSchema::Validator` instances during runtime by providing JSON input to `JSONSchema.from_json()`
* Build `JSONSchema::Validator` objects using a fluent API directly in your application code.
## Usage
### Generating Validators
Generate code using the provided macros which output a reference to a `JSONSchema::Validator` object. You can assign the value to a variable or use it any place an expression can be used.
```crystal
require "jsonschema"
validator = JSONSchema.create_validator "my_schema.json"
```
You can use `create_validator_method` to define a method that returns the reference to the `JSONSchema::Validator`.
```crystal
class RequestBody
JSONSchema.create_validator_method "my_schema.json"
end
```
This is syntactically equivalent to:
```crystal
class RequestBody
def validator : JSONSchema::Validator
JSONSchema.create_validator "my_schema.json"
end
end
```
The `create_validator_method` macro allows you to also customize the method name that is generated by passing a second argument:
```crystal
class ExampleRoute
JSONSchema.create_validator_method "request_schema.json", "request_body_validator"
JSONSchema.create_validator_method "response_schema.json", "response_body_validator"
end
r = ExampleRoute.new
r.request_body_validator # => #<JSONSchema::ObjectValidator:...
r.response_body_validator # => #<JSONSchema::ObjectValidator:...
```
> **Omitting extension**: You can omit the file extension in any of the macros, in which case a file with `.json` as the extension will be loaded.
> ex:
> ```crystal
> JSONSchema.create_validator "my_schema" # => Loads "my_schema.json"
> ```
### Validating JSON
Use the `#validate` method on any generated validator to receive a `JSONSchema::ValidationResult`:
```crystal
require "json"
require "jsonschema"
class RequestBody
JSONSchema.create_validator_method "my_schema.json"
end
request_body = RequestBody.new
input_json = JSON.parse(%{{"test": "example"}})
request_body.validator.validate(input_json) # => JSONSchema::ValidationResult(@status=:success, @errors=[])
```
The `JSONSchema::ValidationResult` will contain either `:success` or `:error` as the `status`. On `:error`, you can check the `@errors` array for a list of `JSONSchema::ValidationError` and respond in your code accordingly.
### Context
When a `ValidationError` is created, it includes a `NodeContext` object which represents the location where the error occurred. You can get the value from this location by using `NodeContext#dig_into`:
```crystal
result = validator.validate(input_json)
result.errors[0].context.dig_into(input_json) # => returns JSON::Any() that wraps value at that location
```
You can get a string path with `NodeContext#to_s` similar to what `jq` ([ref](https://stedolan.github.io/jq/)) uses for pathing.
```crystal
result = validator.validate(input_json)
result.errors[0].context.to_s # => String such as ".person.name" or ".example[2].title"
```
### Create From JSON Input
Use the `#from_json` method to create `JSONSchema::Validator` objects from any parsed JSON. This is a runtime method and can raise an exception for any invalid schema. To return `nil` instead of raising, use `#from_json?`.
```crystal
validator = JSONSchema.from_json(JSON.parse(
<<-JSON
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
JSON
))
validator.validate(JSON.parse("...")) # => JSONSchema::ValidationResult(@status=:success, @errors=[])
```
### Create From Fluent API
The fluent API is a DSL with a concise syntax for generating `JSONSchema::Validator` objects. See the [Fluent](https://aarongodin.github.io/jsonschema/JSONSchema/Fluent.html) class for full usage specification. Here's an example that shows a complex schema represented using the fluent API:
```crystal
require "jsonschema"
js = JSONSchema.fluent
validator = js.object do
prop "first_name", (js.string do
min_length 2
max_length 64
end)
prop "last_name", (js.string do
min_length 2
max_length 64
end)
prop "email", js.string { format "email" }
prop "address", (js.object do
prop "street", js.string
prop "city", js.string
prop "state", js.string
prop "zipcode", js.string
end)
prop "nicknames", (js.array do
min_items 1
items js.string
end)
end
```
### Serialize
You can serialize a validator to its string representation through the standard `#to_json` methods:
```crystal
js = JSONSchema.fluent
validator = js.generic do
any_of(
js.string,
js.number
)
end
puts validator.to_json # {"anyOf":[{"type":"string"},{"type":"number"}]}
```
## json-schema Features
### Core Types
All JSON Schema types _are_ supported!
* `string`
* `number` and `integer`
* `array`
* `object`
* `null`
* `boolean`
The generic keywords `const` and `enum` are also supported.
* `enum` can be provided either as a generic keyword (schema without a `type` value), or on a typed schema.
* `const` may only be provided as a generic keyword.
### Composite Schema
Composite schemas using `not`, `anyOf`, `allOf`, or `oneOf` _are_ supported! These can be used on any schema, including a generic one with no `type`.
### Conditional Schema
Using `dependentRequired`, `dependentSchemas` and `if-then-else` _are_ supported!
### String Formats
JSON Schema provides a number of format keywords that require the validation to restrict the string to values matching the format. This module pulls in [crystal-validator](https://github.com/Nicolab/crystal-validator) to perform most of the validations, and relies on regex for the rest.
### Illogical Schema
It's possible to make a JSON schema that is logically impossible. For example, you could create a composite schema that checks that a value is both a number and a string. The generator tries to prevent this from happening. Since the schema is processed through macros, it seems better to present you a compile error that the schema is illogical than to allow you to use a schema that would be additional work to support in the code, but not actually validate anything.
Calling this out here as this is different behavior than most JSON Schema tools out there. Many libraries implement the rules and rely on the user to write a logical schema.
## Unsupported
These features of JSON Schema are not yet supported, but will be supported in a future release (at least before `1.0.0`).
* [References](https://json-schema.org/understanding-json-schema/structuring.html#ref), `$id`, `$anchor`, and any other relationship-driven schema definition.
* [Media Types](https://json-schema.org/understanding-json-schema/reference/non_json_data.html)
### Dialects
The latest revision of this shard only supports the latest revision of JSON Schema (2020-12). There is not yet support for using a different dialect.
### i18n/Translation
You may provide a translation to this module through `JSONSchema.i18n`. Please [see the API docs](https://aarongodin.github.io/jsonschema/JSONSchema/I18N.html) for documentation.
## Acknowledgements
The source for this shard is inspired by the `ECR` and `JSON` implementations from the std lib. Thanks to the Crystal team for creating an amazing standard library!Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This branch
- Branch
main- Seen
- Jul 19, 2022
- Crystal
>= 1.3.1- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/aarongodin/jsonschema
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 13, 2026
- Synced
- Aug 13, 2026
- Versions
- 1