This project was originally borne from the desire to reverse engineer simple JSON Schema documents into different formats, say from Scala case classes to X
format, but more recently became useful for converting simple schemas into a mongoid document friendly format.
The code is not fully featured but has support for some features as and when it was needed, for example, embedded schema definitions aren't supported but simple embedded references via $ref
URLs are. Further supported can always be added but in the meantime the project may be of use to someone.
$ git clone git@github.com:dataday/json-schema-x.git && cd json-schema-x
$ bundle install --path vendor/bundle
$ bundle exec ruby bin/generate # generates examples from samples
- bin/generate: schema generation file
- schema/input: JSON Schema input files
- schema/results: templated result files
The example shown below was created from a sample schema provided by json-schema.org. This example can be generated using the following command. Executing this command will create example files containing both Ruby as well as the original JSON Schema.
$ bundle exec ruby bin/generate
>> /path/to/json-schema-x/schema/results/address.rb
...
# http://json-schema.org/draft-04/schema#
# An Address following the convention of http://microformats.org/wiki/hcard
class Address
include Mongoid::Document
include Mongoid::Timestamps
field :country_name, type: String
field :region, type: String
field :locality, type: String
field :street_address, type: String
field :postal_code, type: String
field :post_office_box, type: String
field :extended_address, type: String
# :street_address dependents: post_office_box, extended_address
validates :street_address, presence: true
# required fields
validates :locality, :region, :country_name, presence: true
end
__END__
...
{
"schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"country_name": {
"type": "string"
},
"region": {
"type": "string"
},
"locality": {
"type": "string"
},
"street_address": {
"type": "string"
},
"postal_code": {
"type": "string"
},
"post_office_box": {
"type": "string"
},
"extended_address": {
"type": "string"
}
},
"dependencies": {
"post_office_box": [
"street_address"
],
"extended_address": [
"street_address"
]
},
"type": "object",
"required": [
"locality",
"region",
"country_name"
],
"title": "Address",
"description": "An Address following the convention of http://microformats.org/wiki/hcard"
}
Embedded documents require manual intervention. A simple @todo
is added to fields which need special treatment, for example:
# >> foo.rb
...
# field reference: http://json-schema.org/bar
# @todo: specify 'embedded_in :Foo' within class Bar
embeds_one :bar
...
The reference above would normally stem from the original reference shown below:
# >> foo.json
...
"bar": {
"$ref": "http://json-schema.org/bar"
}
...
- bin/validate: schema validation file
- mongoid.yml: mongoid database configuration file
The results of schema generation can be validated by using the following command. This command has been provided for test purposes and can be customised to suit future need.
The approach includes the seralisation of schema test data to create a mongoid friendly instance. This data can then be saved to mongodb but prior to saving the data is validated against it's respective JSON Schema. Errors raised as a result, either through the validation enforced by JSON Schema or at the point of mongoid validation when trying to save the data, and reported on a file by file basis. The JSON Schema used during validation can be found locally to each mongoid schema file, e.g., address.rb.
$ bundle exec ruby bin/validate
address - JSON Schema validation successful
...
There is a small, but no doubt noticable, difference between the JSON Schema input and results. During schema generation, the property key is sanitised and it's format is optionally converted to snake case. This feature can be ironed out if need be.
Tests can be ran using this command.
$ bundle exec rspec spec/* # without coverage
$ export ENV=coverage; bundle exec rspec spec/* # with coverage
The following command will publish documentation associated to the project.
$ bundle exec yardoc
The following commands can be ran for Reek code smell detector and slim-lint, for linting slim templates, respectively.
$ bundle exec reek # ruby code
$ bundle exec slim-lint lib/schema/templates # slim templates
Numerous, but again I hope the project proves useful to someone.
This project uses Semantic Versioning.