Rack::Schema

Gem Version Build Status Dependency Status Code Climate Coverage Status

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::Schema

Your 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: false

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: true

With 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!")
end

Potential Features?

  1. 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.

See Also

  1. HTTP Link Header
  2. json-schema gem