Rule Expressions
On this page
- Overview
- Expression Syntax
- Embedded Expressions
- Multi-Field Expressions
- Expression Evaluation
- Expansions
- Logical Expansions
- Value Expansions
- Environment Expansions
- Request Expansions
- User Expansions
- MongoDB Document Expansions
- Service Expansions
- Operators
- Convert EJSON Values
- Call a Function
- Check Existence
- Compare Values
Overview
A rule expression is a JSON object that you write to control data access with rules. Each expression defines the conditions under which a user can take some action. For example, you can write an expression to control whether a user can read or write data in a MongoDB document or a synced realm.
When App Services evaluates a rule, it resolves each expression
associated with the rule to a boolean value, either true
or
false
.
You can define simple, static expressions that use hardcoded values:
{ "id": "5f6aae9a82989d521a606369" }
You can also write expressions that support arbitrary logic to express dynamic requirements and complex or custom workflows. A dynamic expression can include variables that reflect the current context, called expansions, and can use built-in operators to transform data:
{ "owner": "%%user.id", "%%request.remoteIPAddress": { "$in": "%%values.allowedClientIPAddresses" } }
Expression Syntax
An expression is either a boolean value (i.e. true
or false
) or
a JSON object.
Expression object field names can be a value, an expansion, or an operator. Each field must contain one of a value, an expansion, or a nested expression.
Expression object have the following format:
{ <Value | Expansion | Operator>: <Value | Expression>, ... }
Embedded Expressions
You can embed multiple expression documents in the fields of another expression document to handle complex evaluation logic. Atlas App Services evaluates expressions depth-first, post-order, i.e. it starts at the bottom of the expression tree and works back to the root-level fields by evaluating each expression after all of its embedded expressions.
This expression evaluates to true
only if the number provided
as the someNumber
argument falls in a specific range.
{ "%%args.someNumber": { "%and": [ { "$gt": 0 }, { "$lte": 42 } ] } }
Multi-Field Expressions
When you have more than one field in an expression, that expression evaluates to
true
if and only if every field in the expression evaluates to true. In
other words, App Services treats multiple fields in a single expression as an "AND"
operation.
This third-party service rule expression evaluates to true
only if both
the url
argument was provided and the body.userId
argument matches
the id of the user that called the action.
{ "%%args.url": { "$exists": true }, "%%args.body.userId": "%%user.id" }
Expression Evaluation
Atlas App Services evaluates expressions by first replacing expansions with
their runtime values and then evaluating each field of the expanded
expression document to a boolean expression. If all fields in an
expression evaluate to true
, the expression also evaluates to
true
.
Expression fields evaluate based on the following rules:
- If an expanded field name matches its value, it evaluates to
true
. - If a field's value is an embedded expression, it evaluates to the same value as the embedded expression. See embedded expressions.
If a rule does not explicitly use the %%args
or
%%root
expansion, expression field names default to
checking for arguments or document fields of the same name. For
example, the expression { "url": "https://www.example.com" }
defaults to evaluating the value against %%args.url
in a service
rule and %%root.url
in a MongoDB rule.
Expansions
An expansion is a variable that represents a dynamic value in an expression. Expansions are denoted by two percent signs followed by the expansion name. They can represent:
- the data in a MongoDB document (
%%root
) - a user interacting with your app (
%%user
) - an incoming request (
%%request
) - a static value (
%%partition
) - your app's environment (
%%environment
) - the partition key of a synced realm partition (
%%partition
) - the arguments that were passed to a service action (
%%args
)
When your app evaluates an expression, it replaces each expansion in the expression with a specific value determined by your app's configuration and the context at the time of evaluation.
Logical Expansions
Value Expansions
%%values
- Type:
object
Usable In: Any ExpressionRepresents your application's values. Each field of the object maps a value name to its corresponding JSON value or secret.
ExampleThe following expression evaluates to
true
if the valueadmin_ids
is a list that contains the user's account ID:{ "%%user.id": { "$in": "%%values.admin_ids" } }
Environment Expansions
%%environment
- Type:
object
Usable In: Any ExpressionRepresents the current environment. You can read the environment name (
tag
) and access environment values.Each property of the object maps the name of an environment value to its value in the current environment.
{ "tag": "<Environment Name>" "values": { "<ValueName>": <Value> } } ExampleThe following is a rule expression that evaluates to
true
if the current environment is"production"
and the"baseUrl"
environment value is defined:{ "%%environment.tag": "production", "%%environment.values.baseUrl": { "%exists": true } }
Request Expansions
%%request
- Type:
object
Usable In: Any ExpressionRepresents the incoming request.
{ "httpMethod": "<HTTP Method>", "httpReferrer": "<HTTP Referer Header>", "httpUserAgent": "<HTTP User Agent>", "rawQueryString": "<URL Query String>", "remoteIPAddress": "<IP Address>", "requestHeaders": { "<Header Name>": ["<Header Value>", ...] }, "service": "<Service Name>", "action": "<Endpoint Function or Service Action Name>", "webhookUrl": "<HTTPS Endpoint Route>" }
User Expansions
%%user
- Type:
object
Usable In: Any ExpressionRepresents the user that initiated the request. The user object contains account information, metadata from authentication providers, and custom data from your app.
{ "id": "<User Account ID>", "type": "<normal | server>", "data": { "<Field Name>": <Value>, ... } "custom_data": { "<Field Name>": <Value>, ... } "identities": [ { "providerType": "<Auth Provider Name>", "id": "<Provider User ID" } } %%user.type
- Type:
"normal" | "server"
Usable In: Any ExpressionThe type of user that initiated the request. Evaluates to
"server"
for API key users and"normal"
for all other users.
%%user.custom_data
- Type:
object
Usable In: Any ExpressionThe user's custom data. The exact contents vary depending on your custom user data configuration.
Example"custom_data": { "primaryLanguage": "English", }
%%user.data
- Type:
object
Usable In: Any ExpressionThe user's metadata. The exact contents will vary depending on the authentication provider identities associated with the user.
Example"data": { "name": "Joe Mango", "email": "joe.mango@example.com" }
%%user.identities
- Type:
object[]
Usable In: Any ExpressionA list of all authentication provider identities associated with the user. An identity consists of a unique identifier given to a user by an authorization provider along with the provider's type:
Example"identities": [ { "id": "5bce299457c70db9bd73b8-aajddbkuvomsvcrjjfoxs", "providerType": "local-userpass" } ]
MongoDB Document Expansions
%%this
- Type:
any
Usable In: MongoDB Atlas Data SourcesThe value of a particular field as it exists at the end of a database operation.
%%prev
- Type:
any
Usable In: MongoDB Atlas Data SourcesThe value of a particular field before it is changed by a write operation.
%%root
- Type:
object
Usable In: MongoDB Atlas Data SourcesThe full document as it exists at the end of a database operation.
%%prevRoot
- Type:
object
Usable In: MongoDB Atlas Data SourcesThe full document before it is changed by a write operation.
The following is a MongoDB schema validation expression that
evaluates to true
if either the document previously existed (i.e.
the action is not an insert) or the document's status
field has a
value of "new"
:
{ "%or": [ { "%%prevRoot": { "%exists": %%true } }, { "%%root.status": "new" } ] }
Service Expansions
%%args
- Type:
object
Usable In: Third-Party Services [Deprecated]A document containing the values passed as arguments to a service action. You can access each argument by its parameter name.
ExampleThe following is a Twilio service rule that evaluates to
true
if the sender's phone number (thefrom
argument) matches a specific value:{ "%%args.from": "+15558675309" }
%%partition
- Type:
string | number | BSON.ObjectId
Usable In: Partion-based SyncThe partition key value of the current partition being evaluated.
Operators
An expression operator represents an action or operation within an expression. Operators take in one or more arguments and evaluate to a result value. The type and value of the result depends on the operator you use and the arguments you pass to it.
Expression operators are denoted by strings that begin with either a
single percent sign (%
) or a dollar sign ($
). You can use them
in any expression.
Convert EJSON Values
The following operators allow you to convert values between BSON/EJSON and JSON representations:
%stringToOid
Converts a 12-byte or 24-byte string to an EJSON
objectId
object.Example{ "_id": { "%stringToOid": "%%user.id" } }
%oidToString
Converts an EJSON
objectId
object to a string.Example{ "string_id": { "%oidToString": "%%root._id" } }
%stringToOid
and %oidToString
do not
evaluate JSON operators. You must provide either a literal string/EJSON
object or an expansion that evaluates to one.
Call a Function
The following operators allow you to call functions in your App Services application:
%function
Calls a function with the specified name and arguments. Evaluates to the value that the function returns.
Example{ "%%true": { "%function": { "name": "isEven", "arguments": [42] } } }
Check Existence
The following operators allow you to determine if a value exists in an object or array:
$exists
Checks if the field it is assigned to has any value. Evaluates to a boolean representing the result.
Example{ "url": { "$exists": true } }
Compare Values
The following operators allow you to compare values, including expanded values:
$eq
Checks if the field it is assigned to is equal to the specified value. Evaluates to a boolean representing the result.
Example{ "score": { "$eq": 42 } }
$ne
Checks if the field it is assigned to is not equal to the specified value. Evaluates to a boolean representing the result.
Example{ "numPosts": { "$ne": 0 } }
$gt
Checks if the field it is assigned to is strictly greater than the specified value. Evaluates to a boolean representing the result.
Example{ "score": { "$gt": 0 } }
$gte
Checks if the field it is assigned to is greater than or equal to the specified value. Evaluates to a boolean representing the result.
Example{ "score": { "$gte": 0 } }