Filterung in der REST-API
Verwenden Sie Query-Parameter im PostgREST-Stil, um Ergebnisse zu filtern. Das Format lautet ?field=operator.value:
# Exact matchGET /api/data/products?active=eq.true
# Comparison operatorsGET /api/data/products?price=gt.100GET /api/data/products?price=lte.50
# Multiple filters (AND)GET /api/data/products?active=eq.true&price=gt.10
# IN operator — match any value in a setGET /api/data/products?status=in.(draft,published)
# NOT INGET /api/data/products?status=nin.(archived,deleted)
# Array containsGET /api/data/products?tags=cs.electronics
# Array contains anyGET /api/data/products?tags=csa.(electronics,books)Filter-Operatoren
Abschnitt betitelt „Filter-Operatoren“| Operator | Bedeutung | Beispiel |
|---|---|---|
eq |
Entspricht (==) |
?active=eq.true |
neq |
Entspricht nicht (!=) |
?status=neq.draft |
gt |
Größer als (>) |
?price=gt.100 |
gte |
Größer oder gleich (>=) |
?price=gte.100 |
lt |
Kleiner als (<) |
?price=lt.50 |
lte |
Kleiner oder gleich (<=) |
?price=lte.50 |
in |
In Array | ?status=in.(a,b,c) |
nin |
Nicht in Array | ?status=nin.(a,b) |
cs |
Array enthält | ?tags=cs.value |
csa |
Array enthält mindestens ein Element | ?tags=csa.(a,b) |
like |
Musterabgleich, case-sensitiv (like) |
?sku=like.AB-% |
ilike |
Musterabgleich, case-insensitiv (ilike) |
?name=ilike.%widget% |
nlike |
Entspricht nicht dem Muster (not-like) |
?sku=nlike.TMP-% |
nilike |
Entspricht nicht, case-insensitiv (not-ilike) |
?name=nilike.%test% |
isnull |
Spalte ist NULL (is-null) |
?deleted_at=isnull.null |
notnull |
Spalte ist nicht NULL (is-not-null) |
?deleted_at=notnull.null |
Die vier Muster-Operatoren vergleichen Text. Eine Enum-Spalte wird über ihren Wert
abgeglichen (?status=like.draft%25); bei einer Zahl, einem Datum oder jeder anderen
Spalte, die kein Text ist, ergeben sie einen 400 INVALID_FILTER_OPERATOR.
isnull und notnull ignorieren ihren Wert — der Operator ist die gesamte Bedingung,
und alles nach dem Punkt wird verworfen. Das SDK schreibt .null, daher ist dies
die Schreibweise, die Sie bei der Übertragung sehen werden.
Logische Operatoren
Abschnitt betitelt „Logische Operatoren“Verwenden Sie or, and und not für komplexe Bedingungen:
# OR: match products that are either cheap or on saleGET /api/data/products?or=(price.lt.10,on_sale.eq.true)
# AND: explicit conjunctionGET /api/data/products?and=(active.eq.true,price.gt.0)
# NOT: everything that is not a discontinued in-stock itemGET /api/data/products?not=(discontinued.eq.true,stock.gt.0)not negiert die Konjunktion seiner Bedingungen: not(a) ist NOT a und
not(a,b) ist NOT (a AND b). Es wird zu einem echten SQL-NOT (...) kompiliert
und nicht zu invertierten Operatoren — SQL ist dreiwertig, sodass NOT (a AND b) und
(NOT a) OR (NOT b) in dem Moment nicht mehr übereinstimmen, in dem ein NULL im Spiel ist.
Eine Negation schließt daher Zeilen ein, deren Spalte NULL ist, was der Bedeutung
von NOT entspricht; verknüpfen Sie ein notnull per AND daneben, wenn dies nicht
gewünscht ist.
Eine Gruppe pro Anfrage: or hat Vorrang vor and, und beide vor not. Es
handelt sich um drei Schreibweisen desselben Slots, nicht um drei Filter. Schachteln
Sie stattdessen:
GET /api/data/products?or=(price.lt.10,and(active.eq.true,price.gt.0))GET /api/data/products?not=(or(status.eq.draft,status.eq.archived))Gruppen können bis zu 32 Ebenen tief verschachtelt werden; darüber hinaus wird die
Anfrage mit INVALID_LOGICAL_GROUP abgelehnt.
Eine Bedingung innerhalb einer Gruppe, deren Operator der Dialekt nicht kennt —
?not=(title.contains.x) — ist ein 400 UNKNOWN_FILTER_OPERATOR, genau wie in einem
JSON-where. Sie wird nicht als Gleichheit auf contains.x gelesen, was innerhalb
von not jede Zeile getroffen hätte.
Eine Gruppe grenzt neben den Feldfiltern ein, anstatt sie zu ersetzen — siehe Wie die Filter kombiniert werden.
Der where-JSON-Dialekt
Abschnitt betitelt „Der where-JSON-Dialekt“Die obigen Feldfilter sind eine von zwei Möglichkeiten, einen Filter zu übermitteln.
Die andere ist ein einzelnes JSON-Objekt, welches das OpenAPI-Dokument bei jedem
GET /api/data/{slug} veröffentlicht und welches die verschachtelten Subcollection-Routen
entgegennehmen:
GET /api/data/products?where={"status":["==","active"],"price":[">=",100]}Jeder Schlüssel ist ein Feld, jeder Wert ein kanonisches [operator, value]-Tupel —
dieselben Tupel, die auch das SDK schreibt. Ein Wert kann auch ein vor-serialisierter
Punkt-String ({"status":"eq.active"}) oder ein einfacher Skalar ({"status":"active"})
sein; alle drei kompilieren zur selben Bedingung. Ein Array aus einfachen Werten ist ein
implizites in: {"category":["electronics","gadgets"]} wird gelesen als
["in", ["electronics","gadgets"]], während ein erstes Element in Operatorform, das
kein echter Operator ist (["!!","x"]), ein 400 UNKNOWN_FILTER_OPERATOR ergibt.
Dasselbe Objekt wird überall gleich gelesen, wo es ankommt: hier, im where des SDK,
in einer MCP-Abfrage und im filter des Realtime-Sockets – bei dessen Listen- und
Zählanfragen und seinen Live-Subscriptions.
Der wissenswerte Unterschied: JSON überträgt Typen. ?price=gte.100 sendet
die Zeichenkette "100" und der Treiber castet sie anhand des Spaltentyps, während
?where={"price":[">=",100]} eine Zahl sendet. Für eine Spalte, bei der sich Text-
und numerische Interpretationen unterscheiden — ein Versions-String, ein mit Nullen
aufgefüllter Code —, ist dies der zu wählende Parameter.
Ein fehlerhaftes where führt zu einem 400 INVALID_WHERE und wird nicht stillschweigend
verworfen: Das Verwerfen würde den Lesevorgang ungefiltert ausführen und alles zurückgeben,
was Row-Level Security zufällig erlaubt.
Wie die Filter kombiniert werden
Abschnitt betitelt „Wie die Filter kombiniert werden“?field=op.value, ?where=, ?or=/?and= und ?searchString= sind unabhängig
voneinander, und jeder vorhandene Parameter muss zutreffen:
(field filters and `where`, AND-ed together) AND (the logical group) AND (the search string)Es gibt keine Möglichkeit, diese untereinander mit OR zu verknüpfen. Alles, was
kein einfaches AND dieser Gruppen ist, gehört in einen einzigen or=/and=-Baum.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- REST-API — Endpunkte, Sortierung, Paginierung und das Einbinden von Relationen
- Daten abfragen — Dieselben Filter aus dem typisierten SDK