The Connection wrapper
Every list field in the schema (root-level lists and nested relationship lists) returns a Connection wrapper:
Because the wrapper is consistent at every depth, you can pass
filter, first, skip, and orderBy to a nested list the same way you pass them at the root.
Filter operators
Comparison and text
Most fields support a standard set of operators. The exact set depends on the field type — text fields get string operators, numeric fields get range operators, and so on.Logical composition
AND, OR, and NOT compose any number of clauses. They can nest.
Date helpers
Relative date filters save you from computing exact timestamps.Relational quantifiers
To filter parent records by the state of their related children, usesome, every, and none:
Nested mutations
Every relationship field on a mutation input accepts exactly one of three operations:
The whole nested mutation runs as a single transaction. If any step fails, the entire operation rolls back.
Atomic upserts
Tables with at least one unique column expose anupsert<TableName> mutation. It atomically checks the unique field and runs create or update:
Modifying relationships
TheupdateRelationship mutation changes how a foreign key behaves — cascade behavior, nullability, descriptive metadata. Names map to the underlying database constraint name.
For modeling cardinality and many-to-many patterns at the schema level, see Relationships.
Permissions and authentication
Filters, nested mutations, and upserts all run through the same authorization checks. Read access is required for filter clauses that touch a related table; write access is required for every step of a nested mutation. See Role-Based Access. Authentication tokens come from App Services → Authentication Providers.FAQ
When should I use `every` vs `some`?
When should I use `every` vs `some`?
some is “at least one child matches” — finds parents that have any matching child. every is stricter — all children must match. Note that every also matches parents with zero children, which is sometimes surprising.What's the difference between `connect` and passing a foreign key id directly?
What's the difference between `connect` and passing a foreign key id directly?
connect is the schema-level way to link by a unique field — including non-id columns like an email. Passing a raw foreign key id is shorter, but only works when you already have the id and the column is the primary key.Are nested mutations slower than separate operations?
Are nested mutations slower than separate operations?
Faster, in practice. They run in one round-trip and one database transaction, where separate operations require a round-trip per step and don’t share a transaction. They also avoid orphaned records when a later step fails.
Can I combine `having` with `filter`?
Can I combine `having` with `filter`?
Yes.
filter runs before grouping (SQL WHERE); having runs after (SQL HAVING). Use filter to scope the rows that participate in the aggregation, and having to drop groups whose aggregate doesn’t meet a threshold. See Queries → Grouping and aggregation.What's the maximum nesting depth on filters?
What's the maximum nesting depth on filters?
Deep nesting works for typical use cases. For very deep filter trees, consider the
_query POST endpoint on the REST API — it accepts a JSON body that’s easier to compose in code than a deeply nested GraphQL filter literal.