{"id":13784102,"url":"https://github.com/voxpupuli/json-schema","last_synced_at":"2025-05-14T08:05:05.849Z","repository":{"id":1201628,"uuid":"1110217","full_name":"voxpupuli/json-schema","owner":"voxpupuli","description":"Ruby JSON Schema Validator","archived":false,"fork":false,"pushed_at":"2024-12-02T11:39:51.000Z","size":1144,"stargazers_count":1587,"open_issues_count":104,"forks_count":242,"subscribers_count":65,"default_branch":"master","last_synced_at":"2025-05-14T08:02:51.129Z","etag":null,"topics":["hacktoberfest"],"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/voxpupuli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"vox-pupuli","github":"voxpupuli"}},"created_at":"2010-11-24T20:05:16.000Z","updated_at":"2025-05-09T10:57:29.000Z","dependencies_parsed_at":"2023-07-08T08:01:31.434Z","dependency_job_id":"f45fa964-2698-4727-a362-75801a413b25","html_url":"https://github.com/voxpupuli/json-schema","commit_stats":{"total_commits":747,"total_committers":90,"mean_commits":8.3,"dds":0.7389558232931727,"last_synced_commit":"64e7e9553faa014adcf50003ad821e0b31e527c6"},"previous_names":["hoxworth/json-schema"],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fjson-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fjson-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fjson-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fjson-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voxpupuli","download_url":"https://codeload.github.com/voxpupuli/json-schema/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101586,"owners_count":22014907,"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":["hacktoberfest"],"created_at":"2024-08-03T19:00:35.385Z","updated_at":"2025-05-14T08:05:05.795Z","avatar_url":"https://github.com/voxpupuli.png","language":"Ruby","funding_links":["https://opencollective.com/vox-pupuli","https://github.com/sponsors/voxpupuli"],"categories":["Ruby","Who Uses the Test Suite","JSON Schema Validators"],"sub_categories":["Ruby"],"readme":"# Ruby JSON Schema Validator\n\n[![License](https://img.shields.io/github/license/voxpupuli/json-schema.svg)](https://github.com/voxpupuli/json-schema/blob/master/LICENSE.md)\n[![Test](https://github.com/voxpupuli/json-schema/actions/workflows/test.yml/badge.svg)](https://github.com/voxpupuli/json-schema/actions/workflows/test.yml)\n[![Release](https://github.com/voxpupuli/json-schema/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/json-schema/actions/workflows/release.yml)\n[![RubyGem Version](https://img.shields.io/gem/v/json-schema.svg)](https://rubygems.org/gems/json-schema)\n[![RubyGem Downloads](https://img.shields.io/gem/dt/json-schema.svg)](https://rubygems.org/gems/json-schema)\n[![Donated by Iain Beeston](https://img.shields.io/badge/donated%20by-Iain%20Beeston-fb7047.svg)](#transfer-notice)\n\nThis library is intended to provide Ruby with an interface for validating JSON\nobjects against a JSON schema conforming to [JSON Schema Draft\n6](https://tools.ietf.org/html/draft-wright-json-schema-01). Legacy support for\n[JSON Schema Draft 4](http://tools.ietf.org/html/draft-zyp-json-schema-04),\n[JSON Schema Draft 3](http://tools.ietf.org/html/draft-zyp-json-schema-03),\n[JSON Schema Draft 2](http://tools.ietf.org/html/draft-zyp-json-schema-02), and\n[JSON Schema Draft 1](http://tools.ietf.org/html/draft-zyp-json-schema-01) is\nalso included.\n\nAdditional Resources\n--------------------\n\n- [Google Groups](https://groups.google.com/forum/#!forum/ruby-json-schema)\n- #voxpupuli on irc.libera.chat\n\nVersion 2.0.0 Upgrade Notes\n---------------------------\n\nPlease be aware that the upgrade to version 2.0.0 will use Draft-04 **by\ndefault**, so schemas that do not declare a validator using the `$schema`\nkeyword will use Draft-04 now instead of Draft-03. This is the reason for the\nmajor version upgrade.\n\nVersion 3.0.0 Upgrade Notes\n---------------------------\n\nAll individual changes are documented in the CHANGELOG.md. The biggest change\nis that the new version only supports Ruby 2.5 and newer. Take a look into the\ngemspec file to see the currently supported Ruby version and also\n`.github/workflows/test.yml` to see the Ruby versions we test on.\n\nInstallation\n------------\n\nFrom rubygems.org:\n\n```sh\ngem install json-schema\n```\n\nFrom the git repo:\n\n```sh\ngem build json-schema.gemspec\ngem install json-schema-*.gem\n```\n\nValidation\n-----\n\nThree base validation methods exist:\n\n1. `validate`: returns a boolean on whether a validation attempt passes\n2. `validate!`: throws a `JSON::Schema::ValidationError` with an appropriate message/trace on where the validation failed\n3. `fully_validate`: builds an array of validation errors return when validation is complete\n\nAll methods take two arguments, which can be either a JSON string, a file\ncontaining JSON, or a Ruby object representing JSON data. The first argument to\nthese methods is always the schema, the second is always the data to validate.\nAn optional third options argument is also accepted; available options are used\nin the examples below.\n\nBy default, the validator uses the [JSON Schema Draft\n4](http://tools.ietf.org/html/draft-zyp-json-schema-04) specification for\nvalidation; however, the user is free to specify additional specifications or\nextend existing ones. Legacy support for Draft 1, Draft 2, and Draft 3 is\nincluded by either passing an optional `:version` parameter to the `validate`\nmethod (set either as `:draft1` or `draft2`), or by declaring the `$schema`\nattribute in the schema and referencing the appropriate specification URI. Note\nthat the `$schema` attribute takes precedence over the `:version` option during\nparsing and validation.\n\nFor further information on json schema itself refer to \u003ca\nhref=\"https://json-schema.org/understanding-json-schema\"\u003eUnderstanding\nJSON Schema\u003c/a\u003e.\n\nBasic Usage\n--------------\n\n```ruby\nrequire \"json-schema\"\n\nschema = {\n  \"type\" =\u003e \"object\",\n  \"required\" =\u003e [\"a\"],\n  \"properties\" =\u003e {\n    \"a\" =\u003e {\"type\" =\u003e \"integer\"}\n  }\n}\n\n#\n# validate ruby objects against a ruby schema\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, { \"a\" =\u003e 5 })\n# =\u003e false\nJSON::Validator.validate(schema, {})\n\n#\n# validate a json string against a json schema file\n#\n\nrequire \"json\"\nFile.write(\"schema.json\", JSON.dump(schema))\n\n# =\u003e true\nJSON::Validator.validate('schema.json', '{ \"a\": 5 }')\n\n#\n# raise an error when validation fails\n#\n\n# =\u003e \"The property '#/a' of type String did not match the following type: integer\"\nbegin\n  JSON::Validator.validate!(schema, { \"a\" =\u003e \"taco\" })\nrescue JSON::Schema::ValidationError =\u003e e\n  e.message\nend\n\n#\n# return an array of error messages when validation fails\n#\n\n# =\u003e [\"The property '#/a' of type String did not match the following type: integer in schema 18a1ffbb-4681-5b00-bd15-2c76aee4b28f\"]\nJSON::Validator.fully_validate(schema, { \"a\" =\u003e \"taco\" })\n```\n\nAdvanced Options\n-----------------\n\n```ruby\nrequire \"json-schema\"\n\nschema = {\n  \"type\"=\u003e\"object\",\n  \"required\" =\u003e [\"a\"],\n  \"properties\" =\u003e {\n    \"a\" =\u003e {\n      \"type\" =\u003e \"integer\",\n      \"default\" =\u003e 42\n    },\n    \"b\" =\u003e {\n      \"type\" =\u003e \"object\",\n      \"properties\" =\u003e {\n        \"x\" =\u003e {\n          \"type\" =\u003e \"integer\"\n        }\n      }\n    }\n  }\n}\n\n#\n# with the `:list` option, a list can be validated against a schema that represents the individual objects\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, [{\"a\" =\u003e 1}, {\"a\" =\u003e 2}, {\"a\" =\u003e 3}], :list =\u003e true)\n# =\u003e false\nJSON::Validator.validate(schema, [{\"a\" =\u003e 1}, {\"a\" =\u003e 2}, {\"a\" =\u003e 3}])\n\n#\n# with the `:errors_as_objects` option, `#fully_validate` returns errors as hashes instead of strings\n#\n\n# =\u003e [{:schema=\u003e#\u003cAddressable::URI:0x3ffa69cbeed8 URI:18a1ffbb-4681-5b00-bd15-2c76aee4b28f\u003e, :fragment=\u003e\"#/a\", :message=\u003e\"The property '#/a' of type String did not match the following type: integer in schema 18a1ffbb-4681-5b00-bd15-2c76aee4b28f\", :failed_attribute=\u003e\"TypeV4\"}]\nJSON::Validator.fully_validate(schema, { \"a\" =\u003e \"taco\" }, :errors_as_objects =\u003e true)\n\n#\n# with the `:strict` option, all properties are considered to have `\"required\": true` and all objects `\"additionalProperties\": false`\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, { \"a\" =\u003e 1, \"b\" =\u003e { \"x\" =\u003e 2 } }, :strict =\u003e true)\n# =\u003e false\nJSON::Validator.validate(schema, { \"a\" =\u003e 1, \"b\" =\u003e { \"x\" =\u003e 2 }, \"c\" =\u003e 3 }, :strict =\u003e true)\n# =\u003e false\nJSON::Validator.validate(schema, { \"a\" =\u003e 1 }, :strict =\u003e true)\n\n#\n# with the `:fragment` option, only a fragment of the schema is used for validation\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, { \"x\" =\u003e 1 }, :fragment =\u003e \"#/properties/b\")\n# =\u003e false\nJSON::Validator.validate(schema, { \"x\" =\u003e 1 })\n\n#\n# with the `:validate_schema` option, the schema is validated (against the json schema spec) before the json is validated (against the specified schema)\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, { \"a\" =\u003e 1 }, :validate_schema =\u003e true)\n# =\u003e false\nJSON::Validator.validate({ \"required\" =\u003e true }, { \"a\" =\u003e 1 }, :validate_schema =\u003e true)\n\n#\n# with the `:insert_defaults` option, any undefined values in the json that have a default in the schema are replaced with the default before validation\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, {}, :insert_defaults =\u003e true)\n# =\u003e false\nJSON::Validator.validate(schema, {})\n\n#\n# with the `:version` option, schemas conforming to older drafts of the json schema spec can be used\n#\n\nv2_schema = {\n  \"type\" =\u003e \"object\",\n  \"properties\" =\u003e {\n    \"a\" =\u003e {\n      \"type\" =\u003e \"integer\"\n    }\n  }\n}\n\n# =\u003e false\nJSON::Validator.validate(v2_schema, {}, :version =\u003e :draft2)\n# =\u003e true\nJSON::Validator.validate(v2_schema, {})\n\n#\n# with the `:parse_data` option set to false, the json must be a parsed ruby object (not a json text, a uri or a file path)\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, { \"a\" =\u003e 1 }, :parse_data =\u003e false)\n# =\u003e false\nJSON::Validator.validate(schema, '{ \"a\": 1 }', :parse_data =\u003e false)\n\n#\n# with the `:parse_integer` option set to false, the integer value given as string will not be parsed.\n#\n\n# =\u003e true\nJSON::Validator.validate({type: \"integer\"}, \"23\")\n# =\u003e false\nJSON::Validator.validate({type: \"integer\"}, \"23\", parse_integer: false)\n# =\u003e true\nJSON::Validator.validate({type: \"string\"}, \"123\", parse_integer: false)\n# =\u003e false\nJSON::Validator.validate({type: \"string\"}, \"123\")\n\n#\n# with the `:json` option, the json must be an unparsed json text (not a hash, a uri or a file path)\n#\n\n# =\u003e true\nJSON::Validator.validate(schema, '{ \"a\": 1 }', :json =\u003e true)\n# =\u003e \"no implicit conversion of Hash into String\"\nbegin\n  JSON::Validator.validate(schema, { \"a\" =\u003e 1 }, :json =\u003e true)\nrescue TypeError =\u003e e\n  e.message\nend\n\n#\n# with the `:uri` option, the json must be a uri or file path (not a hash or a json text)\n#\n\nFile.write(\"data.json\", '{ \"a\": 1 }')\n\n# =\u003e true\nJSON::Validator.validate(schema, \"data.json\", :uri =\u003e true)\n# =\u003e \"Can't convert Hash into String.\"\nbegin\n  JSON::Validator.validate(schema, { \"a\"  =\u003e 1 }, :uri =\u003e true)\nrescue TypeError =\u003e e\n  e.message\nend\n\n#\n# with the `:clear_cache` option set to true, the internal cache of schemas is\n# cleared after validation (otherwise schemas are cached for efficiency)\n#\n\nFile.write(\"schema.json\", v2_schema.to_json)\n\n# =\u003e true\nJSON::Validator.validate(\"schema.json\", {})\n\nFile.write(\"schema.json\", schema.to_json)\n\n# =\u003e true\nJSON::Validator.validate(\"schema.json\", {}, :clear_cache =\u003e true)\n\n# =\u003e false\nJSON::Validator.validate(\"schema.json\", {})\n```\n\nExtending Schemas\n-----------------\n\nFor this example, we are going to extend the [JSON Schema Draft\n3](http://tools.ietf.org/html/draft-zyp-json-schema-03) specification by adding\na 'bitwise-and' property for validation.\n\n```ruby\nrequire \"json-schema\"\n\nclass BitwiseAndAttribute \u003c JSON::Schema::Attribute\n  def self.validate(current_schema, data, fragments, processor, validator, options = {})\n    if data.is_a?(Integer) \u0026\u0026 data \u0026 current_schema.schema['bitwise-and'].to_i == 0\n      message = \"The property '#{build_fragment(fragments)}' did not evaluate  to true when bitwise-AND'd with  #{current_schema.schema['bitwise-or']}\"\n      validation_error(processor, message, fragments, current_schema, self, options[:record_errors])\n    end\n  end\nend\n\nclass ExtendedSchema \u003c JSON::Schema::Draft3\n  def initialize\n    super\n    @attributes[\"bitwise-and\"] = BitwiseAndAttribute\n    @uri = JSON::Util::URI.parse(\"http://test.com/test.json\")\n    @names = [\"http://test.com/test.json\"]\n  end\n\n  JSON::Validator.register_validator(self.new)\nend\n\nschema = {\n  \"$schema\" =\u003e \"http://test.com/test.json\",\n  \"properties\" =\u003e {\n    \"a\" =\u003e {\n      \"bitwise-and\" =\u003e 1\n    },\n    \"b\" =\u003e {\n      \"type\" =\u003e \"string\"\n    }\n  }\n}\n\ndata = {\n  \"a\" =\u003e 0\n}\n\ndata = {\"a\" =\u003e 1, \"b\" =\u003e \"taco\"}\nJSON::Validator.validate(schema,data) # =\u003e true\ndata = {\"a\" =\u003e 1, \"b\" =\u003e 5}\nJSON::Validator.validate(schema,data) # =\u003e false\ndata = {\"a\" =\u003e 0, \"b\" =\u003e \"taco\"}\nJSON::Validator.validate(schema,data) # =\u003e false\n```\n\nCustom format validation\n------------------------\n\nThe JSON schema standard allows custom formats in schema definitions which\nshould be ignored by validators that do not support them. JSON::Schema allows\nregistering procs as custom format validators which receive the value to be\nchecked as parameter and must raise a `JSON::Schema::CustomFormatError` to\nindicate a format violation. The error message will be prepended by the property\nname, e.g. [The property '#a']()\n\n```ruby\nrequire \"json-schema\"\n\nformat_proc = -\u003e value {\n  raise JSON::Schema::CustomFormatError.new(\"must be 42\") unless value == \"42\"\n}\n\n# register the proc for format 'the-answer' for draft4 schema\nJSON::Validator.register_format_validator(\"the-answer\", format_proc, [\"draft4\"])\n\n# omitting the version parameter uses [\"draft1\", \"draft2\", \"draft3\", \"draft4\"] as default\nJSON::Validator.register_format_validator(\"the-answer\", format_proc)\n\n# deregistering the custom validator\n# (also [\"draft1\", \"draft2\", \"draft3\", \"draft4\"] as default version)\nJSON::Validator.deregister_format_validator('the-answer', [\"draft4\"])\n\n# shortcut to restore the default formats for validators (same default as before)\nJSON::Validator.restore_default_formats([\"draft4\"])\n\n# with the validator registered as above, the following results in\n# [\"The property '#a' must be 42\"] as returned errors\nschema = {\n  \"$schema\" =\u003e \"http://json-schema.org/draft-04/schema#\",\n  \"properties\" =\u003e {\n    \"a\" =\u003e {\n      \"type\" =\u003e \"string\",\n      \"format\" =\u003e \"the-answer\",\n    }\n  }\n}\nerrors = JSON::Validator.fully_validate(schema, {\"a\" =\u003e \"23\"})\n```\n\nValidating a JSON Schema\n------------------------\n\nTo validate that a JSON Schema conforms to the JSON Schema standard,\nyou need to validate your schema against the metaschema for the appropriate\nJSON Schema Draft. All of the normal validation methods can be used\nfor this. First retrieve the appropriate metaschema from the internal\ncache (using `JSON::Validator.validator_for_name()` or\n`JSON::Validator.validator_for_uri()`) and then simply validate your\nschema against it.\n\n\n```ruby\nrequire \"json-schema\"\n\nschema = {\n  \"type\" =\u003e \"object\",\n  \"properties\" =\u003e {\n    \"a\" =\u003e {\"type\" =\u003e \"integer\"}\n  }\n}\n\nmetaschema = JSON::Validator.validator_for_name(\"draft4\").metaschema\n# =\u003e true\nJSON::Validator.validate(metaschema, schema)\n```\n\nControlling Remote Schema Reading\n---------------------------------\n\nIn some cases, you may wish to prevent the JSON Schema library from making HTTP\ncalls or reading local files in order to resolve `$ref` schemas. If you fully\ncontrol all schemas which should be used by validation, this could be\naccomplished by registering all referenced schemas with the validator in\nadvance:\n\n```ruby\nschema = JSON::Schema.new(some_schema_definition, Addressable::URI.parse('http://example.com/my-schema'))\nJSON::Validator.add_schema(schema)\n```\n\nIf more extensive control is necessary, the `JSON::Schema::Reader` instance used\ncan be configured in a few ways:\n\n```ruby\n# Change the default schema reader used\nJSON::Validator.schema_reader = JSON::Schema::Reader.new(:accept_uri =\u003e true, :accept_file =\u003e false)\n\n# For this validation call, use a reader which only accepts URIs from my-website.com\nschema_reader = JSON::Schema::Reader.new(\n  :accept_uri =\u003e proc { |uri| uri.host == 'my-website.com' }\n)\nJSON::Validator.validate(some_schema, some_object, :schema_reader =\u003e schema_reader)\n```\n\nThe `JSON::Schema::Reader` interface requires only an object which responds to\n`read(string)` and returns a `JSON::Schema` instance. See the [API\ndocumentation](http://www.rubydoc.info/github/ruby-json-schema/json-schema/master/JSON/Schema/Reader)\nfor more information.\n\nJSON Backends\n-------------\n\nThe JSON Schema library currently supports the `json` and `yajl-ruby` backend\nJSON parsers. If either of these libraries are installed, they will be\nautomatically loaded and used to parse any JSON strings supplied by the user.\n\nIf more than one of the supported JSON backends are installed, the `yajl-ruby`\nparser is used by default. This can be changed by issuing the following before\nvalidation:\n\n```ruby\nJSON::Validator.json_backend = :json\n```\n\nOptionally, the JSON Schema library supports using the MultiJSON library for\nselecting JSON backends. If the MultiJSON library is installed, it will be\nautoloaded.\n\nNotes\n-----\n\nThe 'format' attribute is only validated for the following values:\n\n- date-time\n- date\n- time\n- ip-address (IPv4 address in draft1, draft2 and draft3)\n- ipv4 (IPv4 address in draft4)\n- ipv6\n- uri\n\nAll other 'format' attribute values are simply checked to ensure the instance\nvalue is of the correct datatype (e.g., an instance value is validated to be an\ninteger or a float in the case of 'utc-millisec').\n\nAdditionally, JSON::Validator does not handle any json hyperschema attributes.\n\n# Transfer Notice\n\nThis plugin was originally authored by [Iain Beeston](https://github.com/iainbeeston).\nThe maintainer preferred that [Vox Pupuli](https://voxpupuli.org/) take ownership of the module for future improvement and maintenance.\nExisting pull requests and issues were transferred, please fork and continue to contribute [here](https://github.com/voxpupuli/json-schema).\n\n# License\n\nThis gem is licensed under the [MIT license](LICENSE.md).\n\n## Release information\n\nTo make a new release, please do:\n* update the version in VERSION.yml\n* Install gems with `bundle install --with release --path .vendor`\n* generate the changelog with `bundle exec rake changelog`\n* Check if the new version matches the closed issues/PRs in the changelog\n* Create a PR with it\n* After it got merged, push a tag. GitHub actions will do the actual release to rubygems and GitHub Packages\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpupuli%2Fjson-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoxpupuli%2Fjson-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpupuli%2Fjson-schema/lists"}