voxpupuli/json-schema

repository·master·Indexed 23 days ago

https://github.com/voxpupuli/json-schema

A Ruby library for validating JSON objects against JSON Schema specifications, supporting Draft 1 through Draft 6. It provides three primary validation methods: validate, validate!, and fully_validate. The library allows for custom attribute and format validator registration, configurable remote schema resolution via JSON::Schema::Reader, and support for multiple JSON backends including json and yajl-ruby.

Tokens
3.8K
Snippets
6
Records
24
Agent score
82%

What's inside json-schema

  1. Install json-schema via gem

    master

    You can install the json-schema library directly from RubyGems or build it from the git repository.

    From RubyGems:

    gem install json-schema

    From the git repo:

    gem build json-schema.gemspec
    gem install json-schema-*.gem
    gem install json-schema
  2. Control remote schema reading and resolution

    master

    To prevent the library from making HTTP calls or reading local files when resolving $ref pointers, you can use two approaches:

    1. Pre-registering schemas: Use JSON::Validator.add_schema(schema_object) to register all referenced schemas in advance.

    2. Configuring the Schema Reader: You can assign a custom JSON::Schema::Reader to JSON::Validator.schema_reader. The reader must respond to read(string) and return a JSON::Schema instance. You can pass options like :accept_uri or :accept_file to the reader, or provide a proc to :accept_uri to restrict resolution to specific hosts.

    # Pre-registering
    schema = JSON::Schema.new(some_schema_definition, Addressable::URI.parse('http://example.com/my-schema'))
    JSON::Validator.add_schema(schema)
    
    # Custom Reader with host restriction
    schema_reader = JSON::Schema::Reader.new(
      :accept_uri => proc { |uri| uri.host == 'my-website.com' }
    )
    JSON::Validator.validate(some_schema, some_object, :schema_reader => schema_reader)
  3. Extend JSON Schema with custom attributes

    master

    You can extend the JSON Schema specification by creating a class that inherits from JSON::Schema::Attribute and registering it with a validator instance.

    1. Define a class inheriting from JSON::Schema::Attribute and implement self.validate.
    2. Create a validator class inheriting from a specific Draft class (e.g., JSON::Schema::Draft3).
    3. Add your attribute to the @attributes hash in the constructor.
    4. Register the new validator using JSON::Validator.register_validator.
    class BitwiseAndAttribute < JSON::Schema::Attribute
      def self.validate(current_schema, data, fragments, processor, validator, options = {})
        # implementation logic
      end
    end
    
    class ExtendedSchema < JSON::Schema::Draft3
      def initialize
        super
        @attributes["bitwise-and"] = BitwiseAndAttribute
        @uri = JSON::Util::URI.parse("http://test.com/test.json")
        @names = ["http://test.com/test.json"]
      end
    end
    
    JSON::Validator.register_validator(ExtendedSchema.new)
  4. Configure JSON backends

    master

    The library supports json and yajl-ruby backends. If both are installed, yajl-ruby is used by default.

    • Switch backends: Use JSON::Validator.json_backend = :json to prefer the standard JSON library.
    • MultiJSON: If MultiJSON is installed, it is automatically used. To disable this (as MultiJSON support is deprecated), set JSON::Validator.use_multi_json = false.
    JSON::Validator.json_backend = :json
    JSON::Validator.use_multi_json = false
  5. How JSON::Validator options work together

    master

    The Validator class uses a set of default options that can be overridden per call.

    • Strict Mode: Setting strict: true is a shortcut that enables both allPropertiesRequired and noAdditionalProperties.
    • Error Handling: To get error details, you must set record_errors: true. If you also set errors_as_objects: true, the returned errors can be converted to hashes for programmatic inspection.
    • Data Mutation: If insert_defaults: true is passed, the validator will attempt to merge missing values from the schema into the original data object after validation.
  6. Register custom format validators

    master

    You can define custom validation logic for the format keyword in your schemas by registering a proc. The proc receives the value to be checked and must raise a JSON::Schema::CustomFormatError if validation fails.

    • JSON::Validator.register_format_validator(name, proc, [versions]): Registers a new format. If versions is omitted, it applies to all drafts.
    • JSON::Validator.deregister_format_validator(name, [versions]): Removes a validator.
    • JSON::Validator.restore_default_formats([versions]): Restores standard formats.
    format_proc = -> value { 
      raise JSON::Schema::CustomFormatError.new("must be 42") unless value == "42" 
    }
    
    # Register for draft4
    JSON::Validator.register_format_validator("the-answer", format_proc, ["draft4"])
    
    # Use in schema
    schema = {
      "$schema" => "http://json-schema.org/draft-04/schema#",
      "properties" => {
        "a" => { "type" => "string", "format" => "the-answer" }
      }
    }
  7. Use the three base validation methods

    master

    The JSON::Validator provides three primary methods for validation. All methods accept two required arguments: the schema (a Ruby object, JSON string, or file path) and the data to validate (a Ruby object, JSON string, or file path). An optional third argument for options is also accepted.

    1. validate: Returns true if validation passes, false otherwise.
    2. validate!: Raises a JSON::Schema::ValidationError if validation fails.
    3. fully_validate: Returns an array of error messages (strings) if validation fails, or an empty array if it passes.

    By default, the validator uses JSON Schema Draft 4. You can specify older drafts using the :version option (e.g., :draft1, :draft2, :draft3) or by using the $schema attribute within the schema itself.

    require "json-schema"
    
    schema = { "type" => "object", "required" => ["a"], "properties" => { "a" => {"type" => "integer"} } }
    
    # Returns boolean
    JSON::Validator.validate(schema, { "a" => 5 })
    
    # Raises JSON::Schema::ValidationError
    JSON::Validator.validate!(schema, { "a" => "taco" })
    
    # Returns array of error strings
    JSON::Validator.fully_validate(schema, { "a" => "taco" })
  8. Configure JSON::Validator options

    master

    When calling validate or validate!, you can pass an opts hash to customize behavior. Key options include:

    • record_errors: (Boolean) If true, enables error recording.
    • errors_as_objects: (Boolean) If true, returns errors as objects (convertible via .to_hash) instead of strings.
    • insert_defaults: (Boolean) If true, modifies the input data to include default values defined in the schema.
    • validate_schema: (Boolean) If true, validates the schema itself against its metaschema.
    • strict: (Boolean) If true, sets both allPropertiesRequired and noAdditionalProperties to true.
    • allPropertiesRequired: (Boolean) Forces all properties in the schema to be present in the data.
    • noAdditionalProperties: (Boolean) Disallows properties in the data that are not defined in the schema.
    • version: Specifies the JSON schema version to use.
    • fragment: (String) A JSON Pointer (e.g., '#/definitions/item') to validate against a specific part of the schema.
  9. Configure advanced validation options

    master

    The JSON::Validator methods accept several options to customize validation behavior:

    • :list => true: Validates an array of objects against a schema representing individual objects.
    • :errors_as_objects => true: Used with fully_validate to return errors as hashes instead of strings.
    • :strict => true: Treats all properties as "required": true and all objects as "additionalProperties": false.
    • :fragment => "#/path": Validates against only a specific fragment of the schema.
    • :validate_schema => true: Validates the schema itself against the JSON Schema specification before validating the data.
    • :insert_defaults => true: Replaces undefined values in the data with defaults defined in the schema.
    • :parse_data => false: Forces the data argument to be a parsed Ruby object (disallows JSON strings, URIs, or file paths).
    • :parse_integer => false: Prevents string values from being parsed as integers during validation.
    • :json => true: Forces the data argument to be unparsed JSON text.
    • :uri => true: Forces the data argument to be a URI or file path.
    • :clear_cache => true: Clears the internal schema cache after validation.
    • :version => :draftN: Specifies the JSON Schema draft version to use.