Client-SDK
Übersicht
Abschnitt betitelt „Übersicht“Das Paket @rebasepro/client bietet ein typsicheres JavaScript SDK für die Interaktion mit Ihrem Rebase-Backend. Es umfasst:
- Datenoperationen — CRUD mit Filterung, Sortierung und Paginierung
- Abrufen von Relationen — Verwandte Entitäten mit
.include()einbeziehen - Echtzeit-Abonnements — WebSocket-basierte Live-Updates
- Authentifizierung — Token-Verwaltung, Anmeldung, Registrierung
- Speicherung — Datei-Upload und -Download
Installation
Abschnitt betitelt „Installation“pnpm add @rebasepro/clientEinrichtung
Abschnitt betitelt „Einrichtung“import { createRebaseClient } from "@rebasepro/client";
const client = createRebaseClient({ baseUrl: "http://localhost:3001", websocketUrl: "ws://localhost:3001"});Der Client verwaltet Authentifizierungs-Tokens automatisch — sobald sich ein Benutzer anmeldet, enthalten alle nachfolgenden Anfragen das JWT.
Datenoperationen
Abschnitt betitelt „Datenoperationen“Greifen Sie auf jede Sammlung über client.data.<collectionName> (camelCase) oder client.data.collection("slug") (kebab-case) zu:
// Property-style access (auto-converts to kebab-case)client.data.blogPosts // → "blog-posts"client.data.users // → "users"
// Dynamic access by slugclient.data.collection("blog-posts")Suchen (Liste)
Abschnitt betitelt „Suchen (Liste)“// Alle Produkte (Standardlimit: 20)const { data, meta } = await client.data.products.find();
// Mit Paginierung, Filterung und Sortierungconst { data, meta } = await client.data.products.find({ where: { active: true, price: [">=", 100] }, orderBy: "created_at:desc", limit: 25, offset: 0});
// data ist Entity<M>[] — jedes Element hat { id, values, path }// meta hat { total, limit, offset, hasMore }Nach ID suchen
Abschnitt betitelt „Nach ID suchen“const product = await client.data.products.findById(42);// Entität<M> | undefiniertErstellen
Abschnitt betitelt „Erstellen“const newProduct = await client.data.products.create({ name: "New Product", price: 29.99, active: true});
// Mit einer spezifischen IDconst newProduct = await client.data.products.create( { name: "Custom ID Product" }, "my-custom-id");Aktualisieren
Abschnitt betitelt „Aktualisieren“const updated = await client.data.products.update(42, { name: "Updated Name", price: 39.99});Löschen
Abschnitt betitelt „Löschen“await client.data.products.delete(42);Fluent-Query-Builder
Abschnitt betitelt „Fluent-Query-Builder“Verketten Sie Methoden für ausdrucksstärkere Abfragen:
const { data } = await client.data.products .where("price", ">=", 100) .where("active", "==", true) .orderBy("created_at", "desc") .limit(10) .find();Verfügbare Methoden
Abschnitt betitelt „Verfügbare Methoden“| Methode | Beschreibung | Beispiel |
|---|---|---|
.where(field, op, value) | Fügt eine Filterbedingung hinzu | .where("age", ">=", 18) |
.orderBy(field, dir) | Sortiert Ergebnisse | .orderBy("name", "asc") |
.limit(n) | Begrenzt die Ergebnisanzahl | .limit(25) |
.offset(n) | Überspringt die ersten N Ergebnisse | .offset(50) |
.search(text) | Volltextsuche | .search("laptop") |
.include(...relations) | Bezieht verwandte Entitäten ein | .include("author", "tags") |
.find() | Führt die Abfrage aus | Gibt FindResponse<M> zurück |
.listen(onUpdate) | Abonniert Echtzeit-Updates | Gibt unsubscribe() zurück |
Filteroperatoren
Abschnitt betitelt „Filteroperatoren“| Operator | Alias | Beschreibung |
|---|---|---|
"==" | "eq" | Gleich |
"!=" | "neq" | Ungleich |
">" | "gt" | Größer als |
">=" | "gte" | Größer als oder gleich |
"<" | "lt" | Kleiner als |
"<=" | "lte" | Kleiner als oder gleich |
"in" | Wert im Array | |
"not-in" | "nin" | Wert nicht im Array |
"array-contains" | "cs" | Array-Feld enthält Wert |
"array-contains-any" | "csa" | Array-Feld enthält einen der Werte |
Abrufen von Relationen
Abschnitt betitelt „Abrufen von Relationen“Relationen können in Abfrageergebnissen enthalten sein, sodass verwandte Entitäten zusammen mit den primären Daten zurückgegeben werden, anstatt nur deren Fremdschlüssel-IDs.
Verwendung von include() (Fluent)
Abschnitt betitelt „Verwendung von include() (Fluent)“// Spezifische Relationen einbeziehenconst { data } = await client.data.posts .include("author", "categories") .find();
// Alle definierten Relationen einbeziehenconst { data } = await client.data.posts .include("*") .find();Verwendung von find({ include }) (Parameter)
Abschnitt betitelt „Verwendung von find({ include }) (Parameter)“const { data } = await client.data.posts.find({ include: ["author", "categories"]});Kombinieren mit Filtern
Abschnitt betitelt „Kombinieren mit Filtern“const { data } = await client.data.posts .where("status", "==", "published") .include("author") .orderBy("published_at", "desc") .limit(10) .find();Lesen von Relationsdaten
Abschnitt betitelt „Lesen von Relationsdaten“Wenn Relationen enthalten sind, enthält die Antwort sowohl den skalaren Fremdschlüssel als auch das hydrierte Relations-Objekt:
const { data } = await client.data.posts .include("author") .find();
for (const post of data) { // Skalarer Fremdschlüssel — immer vorhanden console.log(post.values.author_id); // "uuid-1234"
// Hydrierte Relation — vorhanden, wenn enthalten console.log(post.values.author?.name); // "Jane Doe"}Hinweis: Ohne
.include("author")wird nur das skalare Feldauthor_idzurückgegeben. Das hydrierteauthor-Objekt istundefined.
Relationsnamen
Abschnitt betitelt „Relationsnamen“Die Relationsnamen, die Sie an include() übergeben, müssen dem relationName entsprechen, der im relations-Array der Sammlung definiert ist. Zum Beispiel:
// Sammlungsdefinitionrelations: [ { relationName: "author", target: () => usersCollection, ... }, { relationName: "categories", target: () => categoriesCollection, ... }]
// SDK-Nutzung — Namen müssen übereinstimmenclient.data.articles.include("author", "categories").find()Echtzeit-Abonnements
Abschnitt betitelt „Echtzeit-Abonnements“Abonnieren Sie Sammlungsänderungen über WebSocket:
// Alle aktiven Produkte abonnierenconst unsubscribe = client.data.products.listen( { where: { active: true }, limit: 50 }, (response) => { console.log("Products updated:", response.data); });
// Abonnement beenden, wenn fertigunsubscribe();Eine einzelne Entität abonnieren:
const unsubscribe = client.data.products.listenById( 42, (entity) => { console.log("Product changed:", entity); });Sie können auch über den Fluent Query Builder abonnieren:
const unsubscribe = client.data.products .where("active", "==", true) .orderBy("created_at", "desc") .limit(20) .listen( (response) => console.log("Updated:", response.data), (error) => console.error("Error:", error) );Der WebSocket-Client verwaltet die Wiederverbindung automatisch.
Authentifizierung
Abschnitt betitelt „Authentifizierung“// Anmeldenconst session = await client.auth.signIn("user@example.com", "password");
// Registrierenconst session = await client.auth.signUp("user@example.com", "password");
// Google OAuthconst session = await client.auth.signInWithGoogle(googleIdToken);
// Token aktualisierenawait client.auth.refreshToken();
// Abmeldenawait client.auth.signOut();
// Aktuellen Benutzer abrufenconst user = client.auth.getUser();Speicherung
Abschnitt betitelt „Speicherung“// Hochladenconst result = await client.storage.uploadFile(file, "products/image.jpg");
// URL abrufenconst url = await client.storage.getDownloadURL("products/image.jpg");
// Löschenawait client.storage.deleteFile("products/image.jpg");Benutzerdefinierte Endpunkte
Abschnitt betitelt „Benutzerdefinierte Endpunkte“Rufen Sie benutzerdefinierte Server-Endpunkte auf (Cloud Functions, benutzerdefinierte Routen usw.):
const result = await client.call<{ summary: string }>("generate-summary", { articleId: 42});Verwendung mit React
Abschnitt betitelt „Verwendung mit React“In einem Rebase-Frontend wird der Client typischerweise einmal erstellt und über einen Kontext geteilt:
const client = createRebaseClient({ baseUrl: API_URL, websocketUrl: WS_URL });
// Pass to Rebase provider<Rebase client={client} ...>Zugriff von jeder Komponente aus:
import { useRebaseClient } from "@rebasepro/core";
function MyComponent() { const client = useRebaseClient(); // Verwenden Sie client.data, client.auth, client.storage}SDK-Generator
Abschnitt betitelt „SDK-Generator“Generieren Sie ein vollständig typisiertes Client-SDK aus Ihren Sammlungsdefinitionen:
rebase generate-sdkDies erstellt TypeScript-Typen für alle Ihre Entitäten, sodass Sie beim Verwenden des Clients Autovervollständigung und Typüberprüfung erhalten. Sowohl skalare Fremdschlüssel als auch Relations-Objekte sind in den generierten Database-Typen enthalten.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Relationen — Definieren Sie Relationen zwischen Sammlungen
- Frontend-Übersicht — React-Framework und Komponenten
- Backend-Übersicht — Serverkonfiguration