Document validation with JSON schema

 

Introduction

MongoDB is schemaless, JSON documents of any format can be stored in collections. Starting from MongoDB version 3.2 rules-based validation is available to enforce a format to documents (more in the  MongoDB documentation) and this is supported by RESTHeart.

On top of this, RESTHeart provides a more general approach for validation based on Request Checkers: a Request Checker can verify write requests based on any condition.

RESTHeart provides “out of the box” the jsonSchema Request Checker that validates the body of write requests against a JSON schema.

JSON Schema specifies a JSON-based format to define the structure of JSON data for validation, documentation, and interaction control. A JSON Schema provides a contract for the JSON data required by a given application, and how that data can be modified.

For more information about JSON Schema refer to json-schema.org; a very good resource is understanding json schema web site too.

The Schema Store and Schema resources

Schema Store resources allow store JSON schemas used for document validation; they are specialized collection resources whose documents must conform to the JSON schema format (specifically to the latest version draft-04)

Schema Store are first class citizens in RESTHeart and the format of their URIs is /<db>/_schemas

Create the db schema store

PUT /db/_schemas

Schema resources are documents of the Schema Store. The following request creates a valid JSON Schema.

PUT /db/_schemas/address {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "address": { "type": "string" },
        "city": { "type": "string" },
        "postal-code": { "type": "string" },
        "country": { "type": "string"}
    },
    "required": ["address", "city", "country"]
}
 
HTTP/1.1 201 Created
...

In JSON Schema, the id property (not to be confused with the _id key) has a special role. This property is auto-generated by RESTHeart as can be noted in the response of the following GET request.

GET /db/_schemas/address
HTTP/1.1 200 OK
...
{
    "$schema": "http://json-schema.org/draft-04/schema#""id": "http://schema-store/test/address#", 
    "_id": "address",  
    ....
}

Document validation

To apply the jsonSchema checker simply define the collection checkers metadata property as follows:

{ "checkers": [ { "name": "jsonSchema", "args": { "schemaId": <schema_id>, "schemaStoreDb": <schema_store_db> } } ] }
Property
Description
Mandatory
schemaId

the _id of the JSON schema to enforce

Yes
schemaStoreDb the db No, if omitted the current db is used.

Example

Create a collection enforcing the address JSON Schema

PUT /db/addresses { "checkers": [  { "name": "jsonSchema", "args": { "schemaId": "address" } } ] }

Now let’s try to create an invalid document.

Try to create an invalid address

POST /db/addresses { "address": "Via D'Annunzio 28" }
 
HTTP/1.1 400 Bad Request
...

{
    "_links": {
        "self": {
            "href": "/test/addresses"
        }
    }, 
    "http status code": 400, 
    "http status description": "Bad Request", 
    "message": "schema check failed, #: 2 schema violations found, #: required key [city] not found, #: required key [country] not found"
}

Passing valid data results in the document creation:

Create a valid documents

POST /test/addresses {"address": "Via D'Annunzio, 28", "city": "L'Aquila", "country": "Italy" }

HTTP/1.1 201 Created...