{"id":17096084,"url":"https://github.com/soylent/jschema","last_synced_at":"2026-06-01T03:30:15.957Z","repository":{"id":12524071,"uuid":"15193929","full_name":"soylent/jschema","owner":"soylent","description":"JSON Schema implementation","archived":false,"fork":false,"pushed_at":"2018-07-05T16:02:44.000Z","size":156,"stargazers_count":31,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-16T00:11:10.464Z","etag":null,"topics":["json-schema"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/soylent.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-14T22:23:26.000Z","updated_at":"2021-08-03T02:44:45.000Z","dependencies_parsed_at":"2022-09-10T22:31:36.903Z","dependency_job_id":null,"html_url":"https://github.com/soylent/jschema","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soylent%2Fjschema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soylent%2Fjschema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soylent%2Fjschema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soylent%2Fjschema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soylent","download_url":"https://codeload.github.com/soylent/jschema/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239993963,"owners_count":19730779,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json-schema"],"created_at":"2024-10-14T14:44:35.554Z","updated_at":"2026-06-01T03:30:15.917Z","avatar_url":"https://github.com/soylent.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSchema\n\nDescribe and validate your JSON data using JSchema – an implementation of JSON\nschema v4. For more information on JSON schema please refer to the official\ndocumentation – [JSON Schema Documentation](http://json-schema.org/).\n\n[![Build Status](https://travis-ci.org/soylent/jschema.svg?branch=master)](https://travis-ci.org/soylent/jschema)\n[![Coverage Status](https://coveralls.io/repos/soylent/jschema/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/soylent/jschema?branch=master)\n[![Code Climate](https://codeclimate.com/github/Soylent/jschema/badges/gpa.svg)](https://codeclimate.com/github/Soylent/jschema)\n\n## Features\n\n - Implements JSON Schema draft 4 strictly according to the specification\n - Small, efficient and thread-safe\n - No dependencies\n - Clean and extensible code\n - Tested on Rubinius, MRI, and JRuby\n\n## Installation\n\nAdd `jschema` to your `Gemfile` and execute `bundle install`.\n\n## Basic usage example\n\n```ruby\nrequire 'jschema'\n\n# Create a new schema describing user profile data\nschema = JSchema.build(\n  'type' =\u003e 'object',\n  'properties' =\u003e {\n    'email'    =\u003e { 'type' =\u003e 'string', 'format' =\u003e 'email' },\n    'password' =\u003e { 'type' =\u003e 'string', 'minLength' =\u003e 6 },\n    'sex'      =\u003e { 'type' =\u003e 'string', 'enum' =\u003e ['m', 'f'] }\n  },\n  'required' =\u003e ['email', 'password']\n)\n\n# Validate input and return an array of validation errors\nschema.validate 'invalid_data'\n# =\u003e [\"`invalid_data` must be an object\"]\n\nschema.validate('email' =\u003e 'user@example.org', 'password' =\u003e 'kielbasa')\n# =\u003e []\n\n# Validate input and return boolean value indicating validation result\nschema.valid? 'invalid_data'\n# =\u003e false\n\nschema.valid?('email' =\u003e 'user@example.org', 'password' =\u003e 'kielbasa')\n# =\u003e true\n```\n\n## More advanced example\n\nThe following example shows how you can validate user's input. In this example\nwe implement a simple service that allows us to search for comics.\n\nFirst let's define schema for the search query. It can also be used as\ndocumentation for our service. We can add `title` and `description` fields for\neach query param.\n\n```javascript\n// comic_search_query.json\n{\n    \"title\": \"Comic search query\",\n    \"description\": \"Fetches lists of comics with optional filters\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"characters\": {\n            \"description\": \"Return only comics which feature the specified characters\",\n            \"type\": \"array\",\n            \"items\": { \"pattern\": \"^\\\\d+$\" },\n            \"minItems\": 1\n        },\n        \"format\": {\n            \"description\": \"Filter by the issue format type (comic or collection)\",\n            \"type\": \"string\",\n            \"enum\": [ \"comic\", \"collection\" ]\n        },\n        \"hasDigitalIssue\": {\n            \"description\": \"Include only results which are available digitally\",\n            \"type\": \"string\",\n            \"enum\": [ \"1\", \"0\" ],\n            \"default\": \"1\"\n        },\n        \"limit\": {\n            \"description\": \"Limit the result set to the specified number of resources\",\n            \"type\": \"integer\",\n            \"minimum\": 1,\n            \"maximum\": 100\n        }\n    },\n    \"required\": [ \"characters\" ]\n}\n```\n\nNow we can use our query schema in order to validate user's input. Here is\nimplementation of the comic search service:\n\n```ruby\n# config.ru\nrequire 'jschema'\nrequire 'rack'\nrequire 'json'\n\nclass ComicSearch\n  class \u003c\u003c self\n    def call(env)\n      request = Rack::Request.new(env)\n\n      # Validate request params using JSON schema\n      validation_errors = query_schema.validate(request.params)\n\n      if validation_errors.empty?\n        # Query is valid, request can be processed further\n        Rack::Response.new('Valid query', 200)\n      else\n        # Query is not valid, show validation errors\n        Rack::Response.new(validation_errors, 400)\n      end\n    end\n\n    private\n\n    def query_schema\n      # Create a new instance of JSchema unless it has\n      # already been created.\n      Thread.current[:schema] ||= begin\n        schema_data = JSON.parse File.read('comic_search_query.json')\n        JSchema.build(schema_data)\n      end\n    end\n  end\nend\n\nrun ComicSearch\n```\n\nRun the service:\n\n    $ rackup -D\n\nMake a valid request:\n\n    $ curl -v --globoff \":9292/?characters[]=1\"\n    ...\n    \u003c HTTP/1.1 200 OK\n\nMake a bad request:\n\n    $ curl -v --globoff \":9292/?characters[]=first\"\n    ...\n    \u003c HTTP/1.1 400 Bad Request\n    \u003c first must match pattern \"^\\\\d+$\"\n\n## Fragments\n\nYou can validate against part of a schema by extracting it into a new schema\nobject with `Schema#fragment`:\n\n```ruby\nschema = JSchema.build(\n  'type' =\u003e 'object',\n  'properties' =\u003e {\n    'email': { '$ref' =\u003e '#/definitions/email' }\n  },\n  'definitions' =\u003e {\n    'email' =\u003e { 'type' =\u003e 'string', 'format' =\u003e 'email' }\n  })\n\nemail_schema = schema.fragment('#/definitions/email')\nemail_schema.valid?('valid@example.com')\n# =\u003e true\n\nemail_schema.valid?('invalidexample.com')\n# =\u003e false\n```\n\n\n## Contributing\n\nPull requests are very welcome!\n\n* Please make sure that your changes don't break the tests by running:\n\n      $ bundle exec rake\n\n* Run a single test suite:\n\n      $ ruby -Ilib test/test_suite.rb\n\n* Run a single test:\n\n      $ ruby -Ilib test/test_suite.rb -n /test_method_name/\n\n## License\n\nMIT License (MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoylent%2Fjschema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoylent%2Fjschema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoylent%2Fjschema/lists"}