JSON-schema

JSON-schema

Feathers Models are based on JSON-schema. JSON-schema is the most popular way to describe the structure of JSON data and, since JSON data is essentially just plain old JavaScript objects, this makes JSON-schema a great fit for Feathers Models.

JSON-schema:

  • has the widest adoption among all standards for JSON validation.
  • is very mature (current version is 6).
  • covers a big part of validation scenarios.
  • uses easy-to-parse JSON documents for schemas.
  • is platform independent.
  • is easily extensible.
  • has 30+ validators for different languages, including 10+ for JavaScript, so no need to code validators yourself.

The validateSchema common hook already uses JSON-data for verification.

Swagger and OpenAPI

Swagger and OpenAPI are 2 more reasons to use JSON-schema.

Swagger is a popular tool which allows you to describe the structure of your APIs so that machines can read them.

Swagger uses a subset of JSON-schema to describe its data formats.

TIP

You can use feathers-swagger to expose your Swagger definitions.

The recent OpenAPI Initiative (OAI), a Linux Foundation project created to advance API technology, provides a foundation for developing interoperability of APIs and other technologies. Its members include Adobe, Google, IBM, Microsoft, Oracle, PayPal, RedHat and Salesforce.

OAI v2 was essentially Swagger. The v3 release is the culmination of nearly two years of collaboration among senior API developers and architects from across multiple industries, such as payment and banking, cloud computing, the Internet of Things, and vendors building API solutions.

OAI's data formats use JSON-schema.

Easy to get started

JSON-schema is easy to write, and there are some great tutorials.

Thankfully, you don't have to learn how to write JSON-schema before you can start writing your app. There is wide support for JSON-schema online, including utilities which you can leverage to write your Feathers Models.

You can

  • Generate a Feathers Model online by pasting a JavaScript object.
  • Generate Feathers Models by providing a utility the contents of your database.
  • Generate Feathers Models from Mongoose schemas or Sequelize models.
  • Generate Feathers Models from Walmart's Joi object validation schemas.

Finally, you can test your JSON-schema by running a utility against your existing data.

More generated code

Cli-plus will write useful modules when you provide a model for a Feathers service. These include:

  • Schemas to valid your data for create, update and patch service calls. (available)
  • A GraphQL endpoint. (available).
  • Schemas for fastJoin to populate your data on the server. (TBA)
  • Generate test data. (TBA)
  • Help generating the UI for

Writing JSON-schema

Here is a typical JSON-schema which contains no field validation:

const productJsonSchema = {
    type: 'object',
    properties: {
        _id: { oneOf: [{ type: 'string' }, { type: 'object' }] }, // handle both MongoDB and NeDB
        checked: { type: 'boolean' },
        name: { type: 'string' },
        price: { type: 'number' },
        tags: {
            type: 'array',
            items: { type: 'string' },
        },
        updatedAt: { type: 'number', format: 'date-time', default: Date.now },
    },
}

Feathers Models can default the type properties, so you can write more concisely:

const productJsonSchema = {
    properties: {
        _id: { type: 'ID' },
        checked: { type: 'boolean' },
        name: {},
        price: { type: 'number' },
        tags: { items: {} },
        updatedAt: { format: 'date-time', default: Date.now },
    },
}

As you can see, JSON-schema is fairly straightforward. It also has extensive capabilities for validating your data.

TIP

You should read this excellent tutorial on JSON-schema written by the author of ajv. The Feathers common hook validateSchema uses ajv to validate data.

TIP

We are not certifying the utilities and websites mentioned below work flawlessly. They are part of the JSON-schema ecosystem and may prove useful. We welcome your feedback on them.

Exploring JSON-schema

You can also convert a JSON object to JSON-schema online at https://jsonschema.net. This provides an interesting way to explore JSON-schema.

Exploring page 1

vTitle


The first thing to do is change ID Type from Relative to None, followed by clicking Generate Schema.

Exploring page 2

vTitle


The type of each JSON data property is specified in the JSON-schema. The tags array is typed as an array with its items, i.e. elements, typed as string.

You can play around with the input JSON, seeing how your changes affect the JSON-schema.

Exploring global options

You can control options for the conversion in the area below Generate Schema. Enable Number Options and check Use number, not integer.

Exploring Number Options 1

vTitle


Followed by clicking Generate Schema.

Exploring Number Options 2

vTitle


You can see that "type": "number" is now used for all numeric values.

TIP

Feathers Models should use "type": "number".

Now check the Metadata and Show default attributes boxes in Global Options, followed by clicking Generate Schema.

Exploring Global Options

vTitle


You can see how the JSON-schema grows in sophistication.

Exploring field options

Refresh the page to get the original https://jsonschema.net/#/editor page.

Once again change ID Type from Relative to None, followed by clicking Generate Schema. This let's us back to our starting point.

Exploring page 2

vTitle


Click the Edit icon to see options for each field in the JSON-schema.

Exploring Field Options 1

vTitle


In the @optional tags <array> panel, click the down arrow in the inner @optional <string> panel to see all the options for the array tags.

Exploring Field Options 2

vTitle


  • Min items to 1.
  • Max items to 4.
  • Minimum length to 2.
  • Maximum length to 16 and press the tab key to properly exit this input field.
Exploring Field Options 3

vTitle


  • Click the diskette/drive icon in the @optional tags <array> panel to save your changes.
  • Do not click Generate Schema.
  • Click the Pretty button at the top of the page.
Exploring Field Options 4

vTitle


You can see that validation rules have been added to the tags entry in the JSON-schema.

Using existing data collections

Some records in a collection many differ from other records. In one record a field may have a numeric value, while in another it may be null. Some records may have fields which others do not.

Utilities exist to scan all the records in your collection and produce a consolidated JSON-schema. You may find these useful in some situations.

Here are two of them.

generate-schema

generate-schema

vTitle


generate-schema Example

vTitle


json-schema-generator

json-schema-generator

vTitle


json-schema-generator Example

vTitle


Using existing database schemas

If you have existing schemas and you'd like to take advantage of the new features of Feathers Models, there are utilities that will convert them into JSON-Schemas:

mongoose-schema-jsonschema and mongoose-jsonschema convert Mongoose schema to JSON-schema.

There are several utilities available available to convert Sequelize models.

Search for utilities for other databases.

Verifying against JSON

Once you have your JSON-schema, you can check it acts as expected by having it verify JSON which you know is valid by, for example, using the online JSON Schema Lint site.

Click the Samples dropdown and chooseSample draft-06 schema and valid document`.

Lint Online 1

vTitle


Or Sample draft-06 schema and **invalid** document.

Lint Online 2

vTitle


TIP

You may have extracted your JSON from someplace and its hard to read. You have a long JSON which is invalid --- someplace. You may find JSONLint useful to prettify and debug your JSON.

Linting you JSON-schema

How do you check your JSON-schema is valid? Well every JSON-schema is itself a JSON object and the official standards JSON-schema org has meta-schemas which specify what JSON-schema should look like.

So you can download the Meta-schemas and use them to verify your JSON-schema, exactly the same way you'd use JSON-schema to verify JSON.

Verifying against data collections

You can verify the compatibility of your JSON-schema and your data collection by using the JSON-schema to verify your collection.

You can use the Feathers common hook validateSchema. Or you may decide its more convenient to call ajv directly.

Verification in tests and build chains

You might some other ajv-based utilities useful.

grunt-jsonschema-ajv is a Grunt plugin for validating files against JSON Schema with ajv.

chai-ajv-json-schema purports to verify data using the expect syntax.

$ref: Modularizing definitions

The field createdAt may be used in several schemas. It would be advantageous to define its characteristics -- such as its minLength and maxLength -- in one place rather than everywhere its used.

We can do this with the $ref keyword.

// src/services/comment/comment.schema.js refers to an external property definition
{
  properties: {
    // ...
    createdAt: { $ref: 'common.json#/definitions/created_at'}
  }
}

// src/refs/common.json contains the definition
{
  "description": "Common JSON-schema definitions.",
  "definitions": {
    "created_at": {
      "description": "Creation date-time.",
      "example": "2018-01-01T01:01:01.001Z",
      "format": "date-time",
      "readOnly": true,
      "type": "string"
    },
  }
}

// src/services/comment/comment.validate.js will be generated with
const base = merge({},
  {
    properties: {
      createdAt: {
        description: "Creation date-time.",
        example: "2018-01-01T01:01:01.001Z",
        format: "date-time",
        readOnly: true,
        type: "string"
      }
    }
  },
);

// src/services/comment/comment.mongoose.js will be generated with
{
  createdAt: String
},

The definition of createdAt in common.json will be merged into the field in comment.schema.js.

You can create a $ref file like common.json with all the common elements in your app. Should the need arise to change some, such as increasing the length of the address field, you need change it in only one place, and then regenerate the project.

You can read about additional features of $ref in the JSON-schema tutorial.

Summary

The online JSON-schema editor provides an easy introduction to JSON-schema, as well as a useful generator of simple JSON-schema.

You will have to read the tutorial sooner or later to understand how to add validation criteria.

There are also ways to generate your JSON-schema from your data, and from existing database schemas.

Finally you can decide to check your JSON-schema against your existing data.