Filter language
Filters express the where clause of an update, delete, or select op. PostgRESTxn uses a structured JSON grammar with operator-maps, identical in shape to filters from MongoDB, Prisma, Sequelize, and Drizzle.
Anatomy
A filter is an object of column entries. Each column entry is itself an operator-map - a non-empty object of {operator: value} pairs.
Translates to:
Note
The language doesn't support OR operators yet. All operators are AND'ed when resolving.
Operator catalog
| Operator | Value type | SQL | Example |
|---|---|---|---|
eq |
scalar | "col" = $N |
{"id": {"eq": 5}} |
neq |
scalar | "col" != $N |
{"status": {"neq": "deleted"}} |
lt |
scalar | "col" < $N |
{"age": {"lt": 18}} |
lte |
scalar | "col" <= $N |
{"age": {"lte": 65}} |
gt |
scalar | "col" > $N |
{"score": {"gt": 100}} |
gte |
scalar | "col" >= $N |
{"score": {"gte": 80}} |
like |
string | "col" LIKE $N |
{"email": {"like": "%@example.com"}} |
ilike |
string | "col" ILIKE $N |
{"name": {"ilike": "alice%"}} |
is |
null / true / false |
"col" IS NULL/TRUE/FALSE |
{"deleted_at": {"is": null}} |
in |
non-empty array | "col" IN ($N1, ...) |
{"id": {"in": [1, 2, 3]}} |
nin |
non-empty array | "col" NOT IN ($N1, ...) |
{"id": {"nin": [4, 5]}} |
not |
another operator-map | NOT (<recursive>) |
{"id": {"not": {"in": [1, 2]}}} |
A few notes on specific operators:
like/ilikeuse standard SQL wildcards in the value:%for any sequence,_for a single character.notrecurses. It wraps another operator-map and negates the result.
Multi-operator examples
Range query (one column, two operators):
Pattern + null check (multiple columns):
{"email": {"ilike": "%@example.com"}, "deleted_at": {"is": null}}
// → "email" ILIKE '%@example.com' AND "deleted_at" IS NULL
Cross-op references in filters
Operator values can be cross-op references. They resolve before the filter is built:
References work inside in / nin arrays too:
Forbidden shapes
These are rejected with a validation_error (HTTP 422):
- Empty operator-map:
{"id": {}}- a column entry must have at least one operator. - Empty list:
{"id": {"in": []}}-in/ninrequire at least one element. - Unknown operator:
{"id": {"foobar": 5}}- operator must be in the catalog. - Wrong value type:
{"id": {"eq": [1, 2]}}-eqrequires a scalar, not an array. iswith non-bool/non-null:{"id": {"is": "yes"}}- only JSONnull/true/false.