Define & Enforce a Schema
On this page
You can control the shape and contents of documents in a collection by defining a schema. Schemas let you require specific fields, control the type of a field's value, and validate changes before committing write operations.
This guide shows you how to define, configure, and deploy a schema for a linked MongoDB Atlas collection.
Note
Federated data sources do not support rules or schemas. You can only access a Federated data source from a system function.
Define a Schema
You can define a schema for a collection in the App Services UI or with the App Services CLI.
When using the App Services UI, you can choose to:
Generate a schema from existing data in the collection, and modify as needed.
Define a schema manually by adding field-level schema definitions.
Navigate to the Schema Screen
In the left navigation menu, click Schema beneath Data Access to open the schema editor. The Collections configuration screen displays in the Collections tab. Atlas App Services scans your linked cluster for existing collections and lists them on the left side of the schema editor.
Find and select your collection from the menu to show the collection configuration on the right side of the schema editor.
Generate a Schema from Existing Data (Optional)
If you already have data in your collection, App Services can sample a subset of the documents in the collection and generate a schema for you based on the sample. If you already have a schema or prefer to define one manually, skip to the next step.
You can configure the number of documents to sample and use the MongoDB query language to limit the sample to specific documents. By default, App Services randomly samples up to 500 documents from the entire collection.
To generate a schema from existing data:
From the collection configuration on the right side of the schema editor, click Generate Schema to open the sample configuration screen.
Specify the sample size, up to a maximum of 50,000 documents.
Optionally, click Advanced and specify a query, projection, and/or sort to refine the sample query. Use the query and sort filters to sample a specific subset of documents and use the projection filter to sample a specific subset of fields from each document.
Click Generate to run the sample query and generate a schema. The process may take up to a minute depending on the number and contents of the sampled documents.
Define or Modify the Schema
You can define a schema manually or modify an existing schema by adding field-level schema definitions.
You may define a single BSON schema for each collection. The root-level type
of each collection schema is an object
schema that represents a document
in the collection. You can define additional schemas for document fields
within the root schema's properties
field.
The fields available in a JSON schema object depend on the type of value that the schema defines. For a list of supported types and details on how to configure them, see schema types.
Example
A group is using App Services to run a voting app where users aged 13 or
older can submit a ranked list of their favorite colors. They store
the votes in a MongoDB collection named votes
where each
document represents a single person's vote. Each vote must include
the person's name, age, and an array of their favorite colors. Each
color has a rank
, name
, and a hexCode
.
The following is a typical document in the votes
collection:
{ "name": "Jane Doe", "age": 42, "favoriteColors": [ { "rank": 1, "name": "RebeccaPurple", "hexCode": "#663399" }, { "rank": 2, "name": "DodgerBlue", "hexCode": "#1E90FF" }, { "rank": 3, "name": "SeaGreen", "hexCode": "#2E8B57" }, ] }
The group can use the following schema to guarantee that the listed
constraints are satisfied for each document in the votes
collection:
{ "bsonType": "object", "required": ["name", "age", "favoriteColors"], "properties": { "name": { "bsonType": "string" }, "age": { "bsonType": "int", "minimum": 13, "exclusiveMinimum": false }, "favoriteColors": { "bsonType": "array", "uniqueItems": true, "items": { "bsonType": "object", "properties": { "rank": { "bsonType": "int" }, "name": { "bsonType": "string" }, "hexCode": { "bsonType": "string", "pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" } } } } } }
Add Change Validation Expressions (Optional)
In addition to configuring the content of each field, you can validate changes
to documents by defining a validation expression in the
validate
field of a schema. Validation expressions can use the
%%prev
and %%prevRoot
expansions to access
a field or document's values before the insert or update operation occurred.
Example
Consider a collection where the document's owner_id
field
represents the owner of each document. The business rules for this
collection specify that once a document has an owner, the value of
owner_id
should never change. We can enforce this constraint
with the following validation expression that ensures that update
operations do not change the owner_id
value unless its to
assign an owner where there was none previously:
"owner_id": { "validate": { "%or": [ { "%%prev": { "%exists": false } }, { "%%prev": "%%this" } ] } }
We could also use the %%prevRoot
expansion to
create the following equivalent validation expression:
"owner_id": { "validate": { "%or": [ { "%%prevRoot.owner_id": { "%exists": false } }, { "%%prevRoot.owner_id": "%%root.owner_id" } ] } }
Save the Schema
After you have configured the schema, click Save. After saving, App Services immediately begins enforcing the schema for all future queries.
Note
Existing documents that do not match the schema are not automatically updated or validated, so future changes to these documents may cause schema validation failures.
Validate Documents Against the Schema
Once you have saved the collection schema, you can validate that existing documents in the collection conform to the schema.
App Services samples documents for validation as it does for automatic schema generation.
To validate the data in a collection:
Click the Run Validation button to open the validation configuration window.
Specify the sample size, up to a maximum of 50,000 documents.
Optionally, click Advanced and specify a query and/or sort to refine the validation to a specific subset of documents.
Click Run Validation to sample documents from the collection and validate each document against the schema.
Once validation is complete, App Services lists any validation errors from the sample in the JSON Validation Errors table. Each row of the table represents a specific type of validation error for a particular field and indicates the number of documents that failed to validate in that way.
For each validation error, you can use the Actions menu to download the raw documents that failed or copy a MongoDB query that finds the failed documents.
Log In to MongoDB Cloud
To configure your app with appservices, you must log in to MongoDB Cloud using an API key scoped to the organization or project that contains the app.
appservices login --api-key="<MongoDB Cloud Public API Key>" --private-api-key="<MongoDB Cloud Private API Key>"
Pull the Latest Version of Your App
To define a document schema with appservices
, you need a local copy of your
application's configuration files.
To pull a local copy of the latest version of your app, run the following:
appservices pull --remote="<Your App ID>"
Tip
You can also download a copy of your application's configuration files from the Deploy > Import/Export App screen in the App Services UI.
Define the Schema
To define or modify the schema for a collection, open the schema.json
configuration file within the collection's configuration directory.
Tip
Scaffold the Collection
If you haven't already defined rules or a schema for the collection, you
need to manually create its configuration directory and schema.json
:
# Create the collection's configuration directory mkdir -p data_sources/<service>/<db>/<collection> # Create the collection's schema file echo '{}' >> data_sources/<service>/<db>/<collection>/schema.json
The root-level schema for every document must be of type object
. You can
use additional schema to configure specific fields within the
properties
array. At a minimum, the schema should resemble the following:
{ "bsonType": "object", "properties": { "<Field Name>": <Schema Document>, ... } }
Define Change Validation (Optional)
You can validate changes to documents by defining a validation
expression in the validate
field of a schema.
Validation expressions can use the %%prev
and
%%prevRoot
expansions to access a field or document's values
before the insert or update operation occurred.
Example
Consider a collection where the document's owner_id
field represents
the owner of each document. The business rules for this collection specify
that once a document has an owner, the value of owner_id
should never
change. We can enforce this constraint with the following validation
expression that ensures that update operations do not change the
owner_id
value unless its to assign an owner where there was none
previously:
"owner_id": { "validate": { "%or": [ { "%%prev": { "%exists": false } }, { "%%prev": "%%this" } ] } }
We could also use the %%prevRoot
expansion to create the
following equivalent validation expression:
"owner_id": { "validate": { "%or": [ { "%%prevRoot.owner_id": { "%exists": false } }, { "%%prevRoot.owner_id": "%%root.owner_id" } ] } }
Validate Null Types
App Services's default behavior is to only accept a single type for each field.
Schema fields are not nullable by default because null
is a unique
BSON type.
You can configure App Services to pass schema validation when you use null
values with optional fields.
Enabling null type validation allows the value for a field to be persisted as
the type in the schema or the BSON null type.
If you do not enable null type schema validation, App Services rejects null
values passed to optional fields. Even if you enable null type validation,
required fields are never nullable.
To enable null type schema validation in the App Services UI:
In the left navigation menu below the Manage header, select App Settings.
On the General tab, navigate to the Null Type Schema Validation section. Toggle the switch to ON.
Click the Save button.