Rack::Schema
Validate your application's responses against JSON Schemas.
Installation
Add this line to your application's Gemfile:
gem 'rack-schema'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rack-schema
Usage
Mount Rack::Schema as middleware in one of the normal manners:
# using config.ru:
use Rack::Schema
run MyApp
# or application.rb:
config.middleware.use Rack::SchemaYour application can now return an HTTP Link header
with a rel attribute value of describedby, and Rack::Schema will
automatically attempt to validate responses against the specified
schema (using the json-schema gem). An example Link
header:
Link: <http://example.com/schemas/response>; rel="describedby"
If your schema applies only to a part of the JSON response, you can
use the anchor attribute to specify a JSON path to the relevant value:
Link: <http://example.com/schemas/widget>; rel="describedby"; anchor="#/widget"
This is actually a mis-use of the anchor attribute, which would
typically be used to specify an anchor within the linked document,
rather than the document being described. JSON schemas already support
the use of the hash fragment on its URI, however, so I've
re-appropriated it. Suggestions for a more compliant tactic are
welcome.
If your response is actually a collection of objects that should all
validate against the same schema, use the collection attribute:
# Assert that the response is an array, and each object within it is a valid widget.
Link: <http://example.com/schemas/widget>; rel="describedby"; collection="collection"
# Assert that the object at '#/widgets' is an array, and each object within it is a valid widget.
Link: <http://example.com/schemas/widget>; rel="describedby"; anchor="#/widgets"; collection="collection"
If the Link header contains multiple applicable links, they will
all be used to validate the response:
# Assert that '#/teams' is an array of valid teams, and '#/score' is a valid score.
Link: <http://example.com/schemas/team>; rel="describedby"; anchor="#/teams"; collection="collection",
<http://example.com/schemas/score>; rel="describedby"; anchor="#/score"
Configuration
Validate Schemas
By default, rack-schema will also instruct the validator to validate
your schema itself as a schema. To disable that behavior:
use Rack::Schema, validate_schemas: falseSwallow Links
If you are running the rack-schema response validator in a
production environment -- which you probably shouldn't be doing --
and you don't want to actually expose the describedby link header
entries to the world, you can tell rack-schema to remove them from
the responses after using them:
use Rack::Schema, swallow_links: trueWith swallow_links on, only the describedby links will be removed;
your pagination or similar links will not be disturbed.
Error Handler
By default, rack-schema will raise a ValidationError if it encounters
any errors in your response JSON. If that's not your bag, you can define
a different error handler by providing a block:
use Rack::Schema do |errors, env, (status, headers, body)|
# Preferably, use a less useless error message.
my_logger.warn("JSON response did not match schema!")
endPotential Features?
- Validate incoming JSON bodies, but I just don't need that right now. And it's unclear how we'd determine what schemas to use, or what we'd do with the errors.