Request Checkers



Request Checkers feature allows to check the request so that, if it does not fulfill some conditions, it returns 400 BAD REQUEST response code thus enforcing a well defined structure to documents.

The checkers collection metadata

In RESTHeart, not only documents but also dbs and collections (and files buckets, schema stores, etc.) have properties. Some properties are metadata, i.e. have a special meaning for RESTheart that controls its behavior.

The collection metadata property checkers allows to declare checkers to be applied to write requests.

checkers is an array of checker objects. A checker object has the following format:

{ "name": <checker_name>,"args": <arguments>, "skipNotSupported": <boolean> }

name of the checker.

args arguments to be passed to the checker no

if true, skip the checking if this checker does not support the request (Checker.doesSupportRequests())



RESTHeart comes with 3 ready-to-be-used checkers:

Custom checkers can also be implemented.

Schema validation with checkContent checker

checkContent is a checker shipped with RESTHeart that allows to enforce a schema to the documents of a collection.

The schema definition is passed via the checker metadata args property as an array of conditions. A condition has the following format

{ "path": <json_path>, "type": <property_type>, "regex": <regex>, "nullable": boolean, "optional": boolean }

If the type is ‘object’ the properties mandatoryFields and optionalFields apply as well:

{ "path": <json_path>, "type": "object", "mandatoryFields": [ <field_names> ], "optionalFields": [ <field_names>] }
Default value

The json path expression that selects the property to verify the condition on.


The type that the selected property must have. It can be the following BSON types:

  • null
  • object
  • array
  • string
  • number
  • boolean
  • objectid
  • date
  • timestamp
  • maxkey
  • minkey
  • symbol
  • code
regex If specified, this regular expression must match the property (or its string representation). No null
nullable If true, no check will be performed if the value of the selected property is null. No false
optional If true, no check will be performed if the property is missing. No false


If the property type is 'object', this is the array of the properties that the object must have.

If specified, the object cannot have any other field, as long as they are not listed in the optionalFields array.

No null

If the property type is 'object', this is the arrayof the properties that the object is allowed optionally to have.

If specified, the object cannot have any other field, as long as they are not listed in the mandatoryFields array.

No null

Json path expressions

A Json path expressions identifies a part of a Json document.

  • It uses the dot notation where the special symbol $ identifies the document itself. 
  • The special char * selects all the properties of an object.
  • The special string [*] selects all the elements of an array.

the [n] notation is not supported, i.e. you cannot use the following json path expression $.array.[3] to select the n-th element of an array.

For example, given the following document:

    "_id": {
        "$oid": "55f6ccf4c2e6be404fdef3dd"
    "string": "hello",
    "object": {
        "pi": 3.14,
        "href": ""
    "array": [1, 2, 3]

The following table shows what document parts, different json path expressions select:

json pat expr selected part
$ the whole document, that is an object
$.string the property string with value "hello"

the object with value:

{ "pi": 3.14, "href": ""}

$.object.* the 2 properties pi and href with values 3.14 (number) and "" (string) respectively
$.object.pi the property pi with numeric value 3.14
$.array the array with value [ 1, 2, 3]
$.array.[*] the 3 elements of the array with numeric values 1, 2 and 3.


The following example creates the collection user enforcing its document to have following fields:

name type mandatory notes
_id string yes the string must satisfy the given regex, that makes sure that the string is a valid email address.
name string yes
password string yes
roles array of strings yes
bio string no
$ http -a a:a PUT \
        {"path":"$", "type":"object", "mandatoryFields": ["_id", "name", "password", "roles"], "optionalFields": ["bio"]},\
        {"path":"$._id", "type":"string", "regex": "^\\u0022[A-Z0-9._%+-]+@[A-Z0-9.-]+\\u005C.[A-Z]{2,6}\\u0022$"},\
        {"path":"$.password", "type":"string"},\
        {"path":"$.roles", "type":"array"},\
        {"path":"$.roles.[*]", "type":"string"},\
        {"path":"$.name", "type":"string"},\
        {"path":"$.bio", "type":"string", "nullable": true}

Limiting file size with checkContentSize

checkContentSize is a checker shipped with RESTHeart that allows to check the size of a request. It is very useful with file resources to limit the maximum size of the uploaded file.

The following example, creates a file bucket resource, limiting the file size from 64 to 32768 bytes:

$ http -a a:a PUT descr="icons" \
checkers:='[{"name":"checkContentSize","args":{"min": 64, "max": 32768}}]

Custom Checkers

A checker is a java class that implements the interface org.restheart.metadata.checkers.Checker.

It only requires to implement the method check() with 3 arguments:

  1. HttpServerExchange exachange
  2. RequestContext context (that is the suggested way to retrieve the information of the request such as the payload) 
  3. BsonValue args (the arguments passed via the args property of the transformer metadata object)
  4. BsonValue confArgs (the arguments passed via the args property specified in the configuration file)
    boolean check(
            HttpServerExchange exchange,
            RequestContext context,
            BsonValue contentToCheck,
            BsonValue args);

     * Specify when the checker should be performed: with BEFORE_WRITE the
     * checkers gets the request data (that may use the dot notation and update
     * operators); with AFTER_WRITE the data is optimistically written to the db
     * and rolled back eventually. Note that AFTER_WRITE helps checking data
     * with dot notation and update operators since the data to check is
     * retrieved normalized from the db.
     * @param context
     * @return BEFORE_WRITE or AFTER_WRITE
    PHASE getPhase(RequestContext context);

     * @param context
     * @return true if the checker supports the requests
    boolean doesSupportRequests(RequestContext context);

Once a checker has been implemented, it can be given a name (to be used as the name property of the checker metadata object) in the configuration file.

The following is the default configuration file section declaring the two off-the-shelf checkers provided with RESTHeart (checkContent and checkContentSize) and a third, custom one.

    - group: checkers
      interface: org.restheart.hal.metadata.singletons.Checker
        - name: checkContent
          class: org.restheart.hal.metadata.singletons.SimpleContentChecker
        - name: checkContentSize
          class: org.restheart.hal.metadata.singletons.ContentSizeChecker
        - name: myChecker
          class: com.whatever.MyChecker

The class of the custom checker must be added to the java classpath. See (How to package custom code)[/learn/custom-code-packaging-howto] for more information.

For example, RESTHeart could be started with the following command:

$ java -server -classpath restheart.jar:custom-checker.jar org.restheart.Bootstrapper restheart.yml

The following code, is an example checker that checks if the number property is an integer between 0 and 10.

package com.whatever;

public class MyChecker implements Checker {
    boolean check(HttpServerExchange exchange, RequestContext context, BsonValue args) {
        BsonValue content = context.getContent();
        BsonValue _value = content.get("number");
        if (context.getMethod() == RequestContext.METHOD.PATCH) {
            if (_value == null) {
                // if this is a PATCH and property value is not in the request, it won't be modified
                return true;
        if (_value != null && _value.isNumber()) {
            Integer value = _value..asInt32().getValue();
            return value < 10 && value > 0;
        } else {
            return false; // BAD REQUEST