JSON Structure Ruby SDK
Ruby SDK for JSON Structure schema validation using FFI bindings to the C library.
Features
- Schema validation - Validate JSON Structure schema documents
- Instance validation - Validate JSON instances against schemas
- High performance - FFI bindings to native C library
- Idiomatic Ruby API - Wrapped in clean, Ruby-friendly classes
- Cross-platform - Works on Linux, macOS, and Windows
Installation
Add this line to your application's Gemfile:
gem 'jsonstructure'
And then execute:
bundle install
Or install it yourself as:
gem install jsonstructure
Binary Distribution
The gem automatically downloads pre-built C library binaries from GitHub releases. No compilation is required during installation.
Supported platforms:
- Linux (x86_64, arm64)
- macOS (x86_64, arm64)
- Windows (x86_64)
If you're developing the gem itself or contributing, see the Development section below for building from source.
Usage
Schema Validation
require 'jsonstructure'
schema = '{"type": "string", "minLength": 1}'
result = JsonStructure::SchemaValidator.validate(schema)
if result.valid?
puts "Schema is valid!"
else
result.errors.each do |error|
puts "Error: #{error.}"
end
end
Instance Validation
require 'jsonstructure'
schema = '{"type": "string", "minLength": 1}'
instance = '"hello"'
result = JsonStructure::InstanceValidator.validate(instance, schema)
if result.valid?
puts "Instance is valid!"
else
result.errors.each do |error|
puts "Error: #{error.}"
puts " Path: #{error.path}" if error.path
end
end
Using Exceptions
Both validators provide a validate! method that raises an exception on validation failure:
require 'jsonstructure'
begin
schema = '{"type": "string"}'
JsonStructure::SchemaValidator.validate!(schema)
puts "Schema is valid!"
rescue JsonStructure::SchemaValidationError => e
puts "Schema validation failed: #{e.}"
e.errors.each { |err| puts " - #{err.}" }
end
begin
instance = '123'
schema = '{"type": "string"}'
JsonStructure::InstanceValidator.validate!(instance, schema)
puts "Instance is valid!"
rescue JsonStructure::InstanceValidationError => e
puts "Instance validation failed: #{e.}"
e.errors.each { |err| puts " - #{err.}" }
end
Working with Validation Results
result = JsonStructure::InstanceValidator.validate(instance, schema)
# Check validity
puts result.valid? # => true or false
puts result.invalid? # => opposite of valid?
# Access errors
result.errors.each do |error|
puts error.code # Error code
puts error.severity # Severity level
puts error. # Human-readable message
puts error.path # JSON Pointer path to error location
puts error.location # Hash with :line, :column, :offset
# Check error type
puts error.error? # true if severity is ERROR
puts error.warning? # true if severity is WARNING
puts error.info? # true if severity is INFO
end
# Get error/warning messages
error_msgs = result. # Array of error messages
warning_msgs = result. # Array of warning messages
API Reference
JsonStructure::SchemaValidator
validate(schema_json)- Validate a schema, returnsValidationResultvalidate!(schema_json)- Validate a schema, raisesSchemaValidationErroron failure
JsonStructure::InstanceValidator
validate(instance_json, schema_json)- Validate an instance against a schema, returnsValidationResultvalidate!(instance_json, schema_json)- Validate an instance, raisesInstanceValidationErroron failure
JsonStructure::ValidationResult
valid?- Returns true if validation passedinvalid?- Returns true if validation failederrors- Array ofValidationErrorobjectserror_messages- Array of error message stringswarning_messages- Array of warning message strings
JsonStructure::ValidationError
code- Error code (integer)severity- Severity level (ERROR, WARNING, or INFO)message- Human-readable error messagepath- JSON Pointer path to error location (may be nil)location- Hash with:line,:column,:offsetkeyserror?,warning?,info?- Check severity level
Thread Safety
This library is thread-safe. Multiple threads can perform validations concurrently without any external synchronization.
Concurrent Validation
require 'jsonstructure'
schema = '{"type": "object", "properties": {"name": {"type": "string"}}}'
# Safe to validate from multiple threads simultaneously
threads = 10.times.map do |i|
Thread.new do
instance = %Q({"name": "Thread #{i}"})
result = JsonStructure::InstanceValidator.validate(instance, schema)
puts "Thread #{i}: #{result.valid? ? 'valid' : 'invalid'}"
end
end
threads.each(&:join)
Implementation Details
- The underlying C library uses proper synchronization primitives (SRWLOCK on Windows, pthread_mutex on Unix) to protect shared state
- Each validation call is independent and does not share mutable state with other calls
- The
at_exitcleanup hook coordinates with active validations to avoid races during process shutdown
Best Practices
Prefer stateless validation: Each
validatecall is independent. There's no need to create validator instances or manage state.Thread-local results: ValidationResult objects returned by
validateare thread-local and can be safely used without synchronization.Exception safety: If a validation raises an exception (e.g., ArgumentError for invalid input), the library state remains consistent.
Development
After checking out the repo, run bundle install to install dependencies.
For Local Development (Building from Source)
When developing the gem with the C library in the same repository:
# Build the C library locally
rake build_c_lib_local
# Run the tests
rake test
The rake test task will attempt to download a pre-built binary first. If that fails (e.g., during development), it will fall back to building the C library from source if available.
For Production Use
Production installations automatically download pre-built binaries from GitHub releases. No local build is required:
# Just install and use
gem install jsonstructure
# The binary will be downloaded automatically on first require
Architecture
This Ruby SDK treats the JSON Structure C library as an external dependency, downloading pre-built binaries from GitHub releases. The architecture consists of:
- C Library Binaries - Pre-built shared libraries (
.so,.dylib,.dll) distributed via GitHub releases - Binary Installer (
lib/jsonstructure/binary_installer.rb) - Downloads and installs platform-specific binaries - FFI Bindings (
lib/jsonstructure/ffi.rb) - Low-level FFI mappings to C functions - Ruby Wrappers - Idiomatic Ruby classes that wrap the FFI calls
SchemaValidator- Schema validationInstanceValidator- Instance validationValidationResult- Result containerValidationError- Error information
This design allows the Ruby SDK to be distributed independently of the C library source code, treating it as a foreign SDK dependency.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/json-structure/sdk.
License
The gem is available as open source under the terms of the MIT License.