Navigation

MongoDB Schema Validation

Stitch uses the same document validation rules that are used in MongoDB Server. In addition to using the standard JSON Schema rules, Stitch adds support for a validate field, which allows you to use Expansions and to call Stitch Functions.

MongoDB Document Validation

MongoDB Stitch validation rules do not override the document validation that may have been set up separately in MongoDB.

Adding a Validation Schema

Validation rules are added to a collection in the Schema tab for the collection:

An example validation schema.

Using the <validate> Field

The <validate> field is unique to Stitch schemas, and provides a way to specify matches. Using Expansions and Stitch Functions, you can ensure a field value matches a specific value. For example, the following schema ensures that the previous value of the field matches the ID of the requesting user:

"user_id" : {
   "validate": { "%%prev": "%%user.id" }
}

You can also call a Stitch function and compare the output of that function to a specific value. For example, if you have a Stitch function named isRole that takes in two parameters – the user’s ID and the name of a role – and returns a boolean value, you call it like this:

"user_role": {
   "validate": {
      "%%true": {
         "%function": {
            "name": "isRole",
            "arguments": ["%%user.id", "doctor"]
         }
      }
   }
}

In the example above, the document is considered valid if the function returns true. You can also compare the output of a function to any value. If a function were written to take in only the user’s ID and return the role of the user as a string value, your validation rule might look like this:

"user_role": {
   "validate": {
      "doctor": {
         "%function": {
            "name": "getUserRole",
            "arguments": ["%%user.id"]
         }
      }
   }
}

Validation Rule Example

The validation rule example below applies to insert/update operations on the collection reports with the following documents:

{
   "_id" : 1,
   "title" : "Pies",
   "about" : { "subject" : "pies", "counts" : { "pages" : 5, "words" : 100 } },
   "type" : "Public",
   "views" : 101
}
{
   "_id" : 2,
   "title" : "Pastries Part 1",
   "about" : { "subject" : "puff pastries", "counts" : { "pages" : 50, "words" : 5000 } },
   "type" : "Public",
   "views" : 21
}
{
  "_id" : 3,
  "title" : "Cakes",
  "about" : { "subject" : "cupcakes", "counts" : { "pages" : 1, "words" : 200 } },
  "type" : "Internal",
  "views" : 50
 }

To ensure that all documents inserted or updated in the reports collection have:

  • type field with one of two values, "Public" or "Internal", and
  • about.counts.words field contains contains a number greater than 0.

You can specify the following validation rule at the document level:

{
  "type": { "%in": [ "Public", "Internal" ] },
  "about.counts.words": { "%type": "number", "%gt": 0 },
  "required": ["type", "about.counts.words"]
}

This validation rule would disallow any insert or update operations that results in documents that do not violate the rule. For example, the following insert operation would fail:

db.reports.insert(
   {
     "title" : "",
     "about" : { "subject" : "", "counts" : { "pages" : 1, "words" : 0 } },
     "type" : "Public",
     "views" : 50
   }
)

You could specify the above validation rule as separate field level validation rules for the type field and about.counts.words field. That is,

  • The type field has the following validation rule:

    {
      "%%this": { "%in": [ "Public", "Internal" ] }
    }
    
  • The about.counts.words field has the following validation rule:

    {
      "%%this": { "%type": "number", "%gt": 0 }
    }
    

Validation Rules and Write Rules

Delete Operations

Validation rules apply for insert and update operations only. Write rules apply to insert, update, and delete operations.

Rule Cascade

Unlike a write rule where the rule at the highest level overrides any rule specified at a lower level, validation rules do not propagate down to lower levels. That is, if a document validation rule and field validation rule exist, the document validation rule has no implication for the field validation.

For example, if the following document-level validation rule exists:

{
  "about.counts.words": { "%exists": 1 }
}

And, the following field-level validation rule exists for the about.counts.words field:

{
  "%%this": {
    "%type": "number",
    "%gt": 0
  }
}

The following insert operation will fail because it fails the field level validation rule even though it passes the document level validation rule:

{
   "title" : "Brioche",
   "about" : { "subject" : "breads", "counts" : { "pages" : 10, "words" : 0 } },
   "type" : "Public",
   "views" : 50
}