README.md in jsi-0.7.0 vs README.md in jsi-0.8.0
- old
+ new
@@ -3,22 +3,24 @@

[](https://coveralls.io/github/notEthan/jsi)
JSI offers an Object-Oriented representation for JSON data using JSON Schemas. Given your JSON Schemas, JSI constructs Ruby modules and classes which are used to instantiate your JSON data. These modules let you use JSON with all the niceties of OOP such as property accessors and application-defined instance methods.
-To learn more about JSON Schema see [https://json-schema.org/](https://json-schema.org/).
+To learn more about JSON Schema see <https://json-schema.org/>.
JSI marries object-oriented programming with JSON Schemas by associating a module with each schema, and extending every instance described by a schema with that module. When an application adds methods to a schema module, those methods can be used on its instances.
A JSI instance aims to offer a fairly unobtrusive wrapper around its JSON data, which is usually a Hash (JSON Object) or Array described by one or more JSON Schemas. JSI instances have accessors for property names described by schemas, schema validation, and other nice things. Mostly though, you use a JSI as you would use its underlying data, calling the same methods (e.g. `#[]`, `#map`, `#repeated_permutation`) and passing it to anything that duck-types expecting `#to_ary` or `#to_hash`.
Note: The canonical location of this README is on [RubyDoc](http://rubydoc.info/gems/jsi/). When viewed on [Github](https://github.com/notEthan/jsi/), it may be inconsistent with the latest released gem, and Yardoc links will not work.
## Example
-Words are boring, let's code. Here's a schema in yaml:
+Words are boring, let's code. You can follow along from the code blocks - install the gem (`gem install jsi`), load an irb (`irb -r jsi`), and copy/paste/hack.
+Here's a schema in yaml:
+
```yaml
$schema: "http://json-schema.org/draft-07/schema"
description: "A Contact"
type: "object"
properties:
@@ -89,11 +91,11 @@
```ruby
bill.phone.map(&:location)
# => ["home"]
```
-We also get validations, as you'd expect given that's largely what json-schema exists to do:
+We also get validations, as you'd expect given that's largely what JSON Schema exists to do:
```ruby
bill.jsi_valid?
# => true
```
@@ -113,11 +115,11 @@
# => #<JSI::Validation::FullResult
# @validation_errors=
# #<Set: {#<JSI::Validation::Error
# message: "instance type does not match `type` value",
# keyword: "type",
-# schema: #{<JSI (JSI::JSONSchemaOrgDraft07) Schema> "type" => "string"},
+# schema: #{<JSI (JSI::JSONSchemaDraft07) Schema> "type" => "string"},
# instance_ptr: JSI::Ptr["phone", 0, "number"],
# instance_document: {"phone"=>[{"number"=>[5, 5, 5]}]}
# >,
# ...
# >
@@ -138,11 +140,11 @@
There's plenty more JSI has to offer, but this should give you a pretty good idea of basic usage.
## Terminology and Concepts
- `JSI::Base` is the base class for each JSI schema class representing instances of JSON Schemas.
-- a "JSI Schema" is a JSON Schema, instantiated as (usually) a JSI::Base described by a metaschema (see the sections on Metaschemas below). a JSI Schema is an instance of the module `JSI::Schema`.
+- a "JSI Schema" is a JSON Schema, instantiated as (usually) a JSI::Base described by a meta-schema (see the section on meta-schemas below). A JSI Schema is an instance of the module `JSI::Schema`.
- a "JSI Schema Module" is a module which represents one schema, dynamically created by that Schema. Instances of that schema are extended with its JSI schema module. applications may reopen these modules to add functionality to JSI instances described by a given schema.
- a "JSI schema class" is a subclass of `JSI::Base` representing one or more JSON schemas. Instances of such a class are described by all of the represented schemas. A JSI schema class includes the JSI schema module of each represented schema.
- "instance" is a term that is significantly overloaded in this space, so documentation will attempt to be clear what kind of instance is meant:
- a schema instance refers broadly to a data structure that is described by a JSON schema.
- a JSI instance (or just "a JSI") is a ruby object instantiating a JSI schema class (subclass of `JSI::Base`). This wraps the content of the schema instance (see `JSI::Base#jsi_instance`), and ties it to the schemas which describe the instance (`JSI::Base#jsi_schemas`).
@@ -152,13 +154,13 @@
JSI supports these JSON Schema specification versions:
| Version | `$schema` URI | JSI Schema Module |
| --- | --- | --- |
-| Draft 4 | `http://json-schema.org/draft-04/schema#` | {JSI::JSONSchemaOrgDraft04} |
-| Draft 6 | `http://json-schema.org/draft-06/schema#` | {JSI::JSONSchemaOrgDraft06} |
-| Draft 7 | `http://json-schema.org/draft-07/schema#` | {JSI::JSONSchemaOrgDraft07} |
+| Draft 4 | `http://json-schema.org/draft-04/schema#` | {JSI::JSONSchemaDraft04} |
+| Draft 6 | `http://json-schema.org/draft-06/schema#` | {JSI::JSONSchemaDraft06} |
+| Draft 7 | `http://json-schema.org/draft-07/schema#` | {JSI::JSONSchemaDraft07} |
## JSI and Object Oriented Programming
Instantiating your schema is a starting point. But, since the major point of object-oriented programming is applying methods to your objects, of course you want to be able to define your own methods. To do this we reopen the JSI module we defined. Referring back to the Example section above, we reopen the `Contact` module:
@@ -188,11 +190,11 @@
`#phone_numbers` is a new method returning each number in the `phone` array - pretty straightforward.
For `#name` and `#name=`, we're overriding existing accessor methods. note the use of `super` - this invokes the accessor methods defined by JSI which these override. You could alternatively use `self['name']` and `self['name']=` in these methods, with the same effect as `super`.
-Working with subschemas is just about as easy as with root schemas.
+Working with subschemas to add methods is just about as easy as with root schemas.
You can subscript or use property accessors on a JSI schema module to refer to the schema modules of its subschemas, e.g.:
```ruby
Contact.properties['phone'].items
@@ -209,12 +211,11 @@
end
bill.phone.first.number_with_dashes
# => "5-5-5"
```
-A recommended convention for naming subschemas is to define them in the namespace of the module of their
-parent schema. The module can then be opened to add methods to the subschema's module.
+A recommended convention for naming subschemas is to define them in the namespace of the module of their parent schema. The module can then be opened to add methods to the subschema's module.
```ruby
module Contact
Phone = properties['phone'].items
module Phone
@@ -240,13 +241,13 @@
The classes used to instantiate JSIs are dynamically generated subclasses of JSI::Base which include the JSI Schema Module of each schema describing the given instance. These are mostly intended to be ignored: applications aren't expected to instantiate these directly (rather, `#new_jsi` on a Schema or Schema Module is intended), and they are not intended for subclassing or method definition (applications should instead define methods on a schema's {JSI::Schema#jsi_schema_module}).
## Registration
-In order for references across documents (generally from a `$ref` schema keyword) to resolve, JSI provides a registry which associates URIs with schemas (or resources containing schemas). This registry is accessible on {JSI.schema_registry} and is a {JSI::SchemaRegistry}.
+In order for references across documents (generally from a `$ref` schema keyword) to resolve, JSI provides a registry (a {JSI::SchemaRegistry}) which associates URIs with schemas (or resources containing schemas). The default registry is accessible on {JSI.schema_registry}.
-Schemas instantiated with `.new_schema`, and their subschemas, are automatically registered with `JSI.schema_registry` if they identify an absolute URI.
+Schemas instantiated with `.new_schema`, and their subschemas, are by default registered with `JSI.schema_registry` if they are identified by an absolute URI. This can be controlled by params `register` and `schema_registry`.
Schemas can automatically be lazily loaded by registering a block which instantiates them with {JSI::SchemaRegistry#autoload_uri} (see its documentation).
## Validation
@@ -256,17 +257,17 @@
- The `format` keyword does not perform any validation.
- Regular expressions are interpreted by Ruby's Regexp class, whereas JSON Schema recommends interpreting these as ECMA 262 regular expressions. Certain expressions behave differently, particularly `^` and `$`.
- Keywords `contentMediaType` and `contentEncoding` do not perform validation.
-## Metaschemas
+## Meta-Schemas
-A metaschema is a schema which describes schemas. Likewise, a schema is an instance of a metaschema.
+A meta-schema is a schema that describes schemas. Likewise, a schema is an instance of a meta-schema.
-In JSI, a schema is generally a JSI::Base instance whose schemas include a metaschema.
+In JSI, a schema is generally a JSI::Base instance whose schemas include a meta-schema.
-A self-descriptive metaschema - most commonly one of the JSON schema draft metaschemas - is an object whose schemas include itself. This is instantiated in JSI as a JSI::MetaschemaNode, a special subclass of JSI::Base.
+A self-descriptive meta-schema - most commonly one of the JSON schema draft meta-schemas - is an object whose schemas include itself. This is instantiated in JSI as a JSI::MetaSchemaNode, a special subclass of JSI::Base.
## ActiveRecord serialization
A really excellent place to use JSI is when dealing with serialized columns in ActiveRecord.
@@ -280,10 +281,10 @@
class User < ActiveRecord::Base
serialize :contact_info, JSI::JSICoder.new(Contact)
end
```
-Now `user.contact_info` will be instantiated as a `Contact` JSI instance, from the JSON type in the database, with Contact's accessors, validations, and user-defined instance methods.
+Now `user.contact_info` will be instantiated as a `Contact` JSI instance, from the JSON type in the database, with Contact's accessors, validations, and application-defined instance methods.
See the gem [`arms`](https://github.com/notEthan/arms) if you wish to serialize the dumped JSON-compatible objects further as text.
## Keying Hashes (JSON Objects)