Meet your mate Jimmy. He's a top bloke.
Writing JSON schemas is as tedious as a tax audit. But now, thanks to everyone's new best friend Jimmy, it's easier than shooting the side of a barn with a very easy-to-use projectile weapon.
You guessed it:
$ gem install jimmy
Here's another doozy:
require 'jimmy'
Wasn't that a shock. Let's move on.
Jimmy replaces .json
JSON schemas files with .rb
files. Here's a simple example:
# city.rb
object do
string :name, min_length: 2
string :postcode, /^\d{4}$/
require all
end
This compiles to:
{
"$schema": "https://my.domain.kom/city#",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 2
},
"postcode": {
"type": "string",
"pattern": "^\\d{4}$"
},
"required": ["name", "zipcode"],
"additionalProperties": false
}
}
Crikey! That's a bit of a difference. Let's take a look at a more complex (and contrived) example:
# types/country_code.rb
string /^[A-Z]{2}$/
# types/geopoint.rb
object do
number :latitude, -90..90
number :longitude, -180..180
end
# city.rb
object do
string :name, min_length: 2
string :postcode, /^\d{4}$/
integer :population
geopoint :location
country_code :country
array :points_of_interest do
object do
string :title, 3..150
integer :popularity, [1, 3, 5, 7]
geopoint :location
boolean :featured
require :title
end
end
require all - :location
end
Here's the full result (though we expect you get the gist of it by now):
{
"$schema": "https://my.domain.kom/city#",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 2
},
"postcode": {
"type": "string",
"pattern": "^\\d{4}$"
},
"population": {
"type": "integer"
},
"location": {
"$ref": "/types/geopoint#"
},
"country": {
"$ref": "/types/country_code#"
},
"points_of_interest": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 3,
"maxLength": 150
},
"popularity": {
"type": "integer",
"enum": [1, 3, 5, 7]
},
"location": {
"$ref": "/types/geopoint#"
},
"featured": {
"type": "boolean"
}
},
"required": [
"title"
],
"additionalProperties": false
}
}
},
"required": [
"name",
"postcode",
"population",
"country",
"points_of_interest"
],
"additionalProperties": false
}