FSL collection schema: Check constraint definitions
Learn: Check constraints |
---|
A check constraint ensures a document field’s values meet a pre-defined rule.
You write the rule as a read-only FQL
predicate. Fauna only allows
document writes if the predicate evaluates to true
. For example, you can check
that field values are in an allowed range.
You define check constraints as part of an FSL collection schema:
collection Product {
...
// Check constraint. `Product` document writes are
// only allowed if the `stock` field value is zero or greater.
check stockIsValid (product => product.stock >= 0)
...
}
You can create and manage schema using any of the following:
Fauna stores each collection schema as an FQL document in the
Collection
system collection. The Collection
document’s constraints
field contains FQL
versions of the collection’s check constraint definitions.
Properties
Parameter | Type | Required | Description |
---|---|---|---|
constraintName |
Yes |
Check constraint predicate name, which must be unique for the collection. The constraintName identifies the constraint in error messages. |
|
predicateBody |
Yes |
An anonymous, read-only FQL
function that evaluates to The function is passed one argument: an object containing the document to write. The function runs using the built-in |
Discussion
Check constraints can read, call UDFs, and use computed fields but can’t write. A constraint that tries to write results in an evaluation error.
Multiple check constraints can be defined for the collection and a check constraint can evaluate multiple document fields, or multiple values or ranges for a field..
When a document is created, updated, or replaced, all defined check constraints are evaluated by applying the check constraint, which can have four possible outcomes:
-
The predicate returns true. The write to the document is allowed.
-
The predicate returns false or null. The query, including the write to the document, fails.
-
The predicate returns a non-boolean non-null value. The query, including the write to the document, fails.
-
The predicate fails to evaluate, possibly caused by divide-by-zero, stack overflow, timeout errors, or
abort()
is called. The query, including the write to the document, fails. If a check constraint is failed by calling abort, the argument to abort is returned as if the query were failed by calling abort in the query.
Check constraints aren’t applied retroactively to existing data in the database.
Check constraints should be defined defensively to handle the conditions that the field might not exist or might have a different type.
The check constraint is evaluated on the document version when the document is written, not what currently exists. When a check constraint runs on an update operation, it operates on the document with the update applied. When a check constraint runs on a replace operation, it operates on the version that is replacing the original.
Check constraints aren’t evaluated on delete queries.
Check constraint errors
When a query fails a check constraint, the Core HTTP API’s
Query endpoint
rejects the query and returns an error with the constraint_failure
error code.
The error includes a constraint_failures
array. The array contains information
about the constraints that triggered the error:
{
"error": {
"code": "constraint_failure",
"message": "Failed to create document in collection `Product`.",
"constraint_failures": [
{
"paths": [],
"message": "Document failed check constraint `stockIsValid`"
}
]
},
...
}
Fauna’s client drivers include classes for constraint errors:
-
JavaScript driver:
ConstraintFailureError
-
Python driver:
FaunaError.constraint_failures
-
Go driver:
ErrConstraintFailure
-
.NET/C# driver:
ConstraintFailures
-
JVM driver:
ConstraintFailureException
Check constraint behavior
Check constraints are evaluated immediately after a write is registered in the query, before the write is committed. All check constraints for the collection are automatically evaluated on the new document state.
If any check constraint fails, the entire query transaction is aborted — no part of the query after the write is evaluated, and no changes from before the write take effect.
Check constraints evaluate against the pending document state. For example,
if a check constraint includes an expression such
as Collection.byField(doc.foo).count()
, the query includes the document
being written in its results.
Examples
Basic example
-
Given a
hasFunds
check constraint for theCustomer
collection, which validates that a customer balance is greater than or equal to zero, and a customer who currently has a positive balance:collection Customer { ... check hasFunds((doc) => doc.balance >= 0) ... }
And given the following
Customer
collection document:{ id: "388093102421704737", coll: Customer, ts: Time("2099-06-25T12:14:29.440Z"), name: "Alice Appleseed", email: "alice.appleseed@example.com", ..., balance: 21
-
Verify check constraint validation by trying to set the balance to less than zero:
Customer.byId("111")!.update({ balance: -50 })
constraint_failure: Failed to update document with id 111 in collection `Customer`. error: Failed to update document with id 111 in collection `Customer`. constraint failures: Document failed check constraint `hasFunds` at *query*:1:29 | 1 | Customer.byId("111")!.update({ balance: -50 }) | ^^^^^^^^^^^^^^^^^^ |
The
hasFunds
check constraint catches the constraint violation. Notice that the error message includes the name of the check constraint predicate.
Shorthand syntax
You can use shorthand syntax in a check constraint’s predicate function. For example:
collection Customer {
...
check isAdult(.age >= 18)
...
}
Or:
collection Customer {
...
check isAdult(doc => doc.age >= 18)
...
}
Is equivalent to:
collection Customer {
...
check isAdult((doc) => doc.age >= 18)
...
}
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!