Project

rack-spec

0.05
No release in over 3 years
Low commit activity in last 3 years
JSON Schema based Rack middlewares
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

>= 0.0.3
>= 0
 Project Readme

Rack::JsonSchema

CI

JSON Schema based Rack middlewares.

  • Rack::JsonSchema::RequestValidation
  • Rack::JsonSchema::ResponseValidation
  • Rack::JsonSchema::Mock
  • Rack::JsonSchema::ErrorHandler
  • Rack::JsonSchema::Docs
  • Rack::JsonSchema::SchemaProvider
  • specup

Usage

str = File.read("schema.json")
schema = JSON.parse(str)

use Rack::JsonSchema::Docs, schema: schema
use Rack::JsonSchema::SchemaProvider, schema: schema
use Rack::JsonSchema::ErrorHandler
use Rack::JsonSchema::RequestValidation, schema: schema
use Rack::JsonSchema::ResponseValidation, schema: schema if ENV["RACK_ENV"] == "test"
use Rack::JsonSchema::Mock, schema: schema if ENV["RACK_ENV"] == "mock"

Rack::JsonSchema::RequestValidation

Validates request and raises errors below. The rack will automatically look into the corresponding hypermedia definitions.

  • Rack::JsonSchema::RequestValidation::InvalidContentType
  • Rack::JsonSchema::RequestValidation::InvalidJson
  • Rack::JsonSchema::RequestValidation::InvalidParameter
  • Rack::JsonSchema::RequestValidation::LinkNotFound
$ curl http://localhost:8080/users
{
  "id": "link_not_found",
  "message": "Not found"
}

$ curl http://localhost:8080/apps -H "Content-Type: application/json" -d "invalid-json"
{
  "id": "invalid_json",
  "message": "Request body wasn't valid JSON"
}

$ curl http://localhost:8080/apps -H "Content-Type: text/plain" -d "{}"
{
  "id": "invalid_content_type",
  "message": "Invalid content type"
}

$ curl http://localhost:8080/apps -H "Content-Type: application/json" -d '{"name":"x"}'
{
  "id": "invalid_parameter",
  "message": "Invalid request.\n#/name: failed schema #/definitions/app/links/0/schema/properties/name: Expected string to match pattern \"/^[a-z][a-z0-9-]{3,50}$/\", value was: x."
}

Rack::JsonSchema::ResponseValidation

Validates response and raises errors below.

  • Rack::JsonSchema::ResponseValidation::InvalidResponseContentType
  • Rack::JsonSchema::ResponseValidation::InvalidResponseType
$ curl http://localhost:8080/apps
{
  "id": "invalid_response_content_type",
  "message": "Response Content-Type wasn't for JSON"
}

$ curl http://localhost:8080/apps
{
  "id": "invalid_response_type",
  "message": "#: failed schema #/definitions/app: Expected data to be of type \"object\"; value was: [\"message\", \"dummy\"]."
}

Rack::JsonSchema::Mock

Generates dummy response from JSON schema.

$ curl http://localhost:8080/apps
[
  {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example"
  }
]

$ curl http://localhost:8080/apps/01234567-89ab-cdef-0123-456789abcdef
{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "example"
}

$ curl http://localhost:8080/apps/1 -d '{"name":"example"}'
{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "example"
}

$ curl http://localhost:8080/recipes
{
  "id": "example_not_found",
  "message": "No example found for #/definitions/recipe/id"
}

Rack::JsonSchema::ErrorHandler

Returns appropriate error response including following properties when RequestValidation raises error.

  • message: Human readable message
  • id: Error type identifier listed below
  • example_not_found
  • invalid_content_type
  • invalid_json
  • invalid_parameter
  • invalid_response_content_type
  • invalid_response_type
  • link_not_found

Here is a tree of all possible errors defined in Rack::JsonSchema.

StandardError
|
Rack::JsonSchema::Error
|
|--Rack::JsonSchema::Mock::Error
|  |
|  `--Rack::JsonSchema::Mock::ExampleNotFound
|
|--Rack::JsonSchema::RequestValidation::Error
|  |
|  |--Rack::JsonSchema::RequestValidation::InvalidContentType
|  |
|  |--Rack::JsonSchema::RequestValidation::InvalidJson
|  |
|  |--Rack::JsonSchema::RequestValidation::InvalidParameter
|  |
|  `--Rack::JsonSchema::RequestValidation::LinkNotFound
|
`--Rack::JsonSchema::ResponseValidation::Error
   |
   |--Rack::JsonSchema::ResponseValidation::InvalidResponseContentType
   |
   `--Rack::JsonSchema::ResponseValidation::InvalidResponseType

Rack::JsonSchema::Docs

Returns API documentation as text/html (GET /docs) or text/plain (GET /docs.md).

  • You can give path option to change default path: GET /docs
  • API documentation is powered by jdoc gem
  • This middleware is also bundled in the specup executable command

Rack::JsonSchema::SchemaProvider

Serves JSON Schema at GET /schema.

  • You can give path option to change default path: GET /schema
  • This middleware is also bundled in the specup executable command

specup

specup executable command is bundled to rackup handy mock API server. It validates requests, and returns dummy response, also returns auto-generated API documentation at GET /docs, and JSON Schema itself at GET /schema.

$ specup schema.json
[2014-06-06 23:01:35] INFO  WEBrick 1.3.1
[2014-06-06 23:01:35] INFO  ruby 2.0.0 (2013-06-27) [x86_64-darwin12.5.0]
[2014-06-06 23:01:35] INFO  WEBrick::HTTPServer#start: pid=24303 port=8080

$ curl :8080/docs
# Example API
* [App](#app)
 * [GET /apps](#get-apps)
 * [POST /apps](#post-apps)
 * [GET /apps/:id](#get-appsid)
 * [PATCH /apps/:id](#patch-appsid)
 * [DELETE /apps/:id](#delete-appsid)
* [Recipe](#recipe)
 * [GET /recipes](#get-recipes)
...

$ curl :8080/schema
HTTP/1.1 200 OK
{
  "$schema": "http://json-schema.org/draft-04/hyper-schema",
  "definitions": {
    "app": {
      "$schema": "http://json-schema.org/draft-04/hyper-schema",
      "description": "An app is a program to be deployed.",
      "id": "schemata/app",
      "title": "App",
      ...
    }
  }
}

$ curl :8080/apps/1
[
  {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example"
  }
]

$ curl :8080/apps -H "Content-Type: application/json" -d '{"name":1}'
{
  "id": "invalid_parameter",
  "message": "Invalid request.\n#/name: failed schema #/definitions/app/links/0/schema/properties/name: Expected data to be of type \"string\"; value was: 1."
}