Læs og skriv data med GraphQL i Fabric Apps

Fabric Apps leverer en type-sikker GraphQL-klient, der lader dig udføre oprettelse, læsning, opdatering og sletning uden at skrive rå forespørgsler. Klienten genererer automatisk GraphQL fra dine metodekald og returnerer typede enheder baseret på dine datamodeldefinitioner.

Forudsætninger

  • Et Fabric Apps-projekt med definerede datamodeller. Se Definér datamodeller.
  • Backend-tjenesterne kører lokalt eller implementeres til Fabric.

Initialiser klienten

Instansier RayfinClient med din backend-URL, publicerbar nøgle og skematype:

import { RayfinClient } from '@microsoft/rayfin-client';
import type { Note } from '../rayfin/data/Note';
import type { Notebook } from '../rayfin/data/Notebook';

type AppSchema = { 
  Note: Note;
  Notebook: Notebook;
};

const client = new RayfinClient<AppSchema>({
  baseUrl: import.meta.env.VITE_RAYFIN_API_URL ?? 'http://localhost:5168',
  publishableKey: 'pk-your-project-key',
});

Det generiske typeargument gør det muligt for TypeScript at levere autofuldførelse og typekontrol for alle dataoperationer.

Læs data

Få adgang til enhedssamlinger gennem client.data.<EntityName>. Fluent API'et tilbyder metoder til forespørgsler, filtrering, sortering og paginering.

Hent alle poster

const notes = await client.data.Note.select([
  'id',
  'title',
  'content',
  'createdAt',
  'isPinned',
]).execute();

Hent en enkelt post efter primærnøgle

const note = await client.data.Note.findByPk('00000000-0000-0000-0000-000000000000');

Dette returnerer hele enheden, eller null hvis der ikke findes nogen post med det ID.

Filterposter

Brug metoden where() til at filtrere resultater:

const pinnedNotes = await client.data.Note.select([
  'id',
  'title',
  'isPinned',
])
  .where({ isPinned: { eq: true } })
  .execute();

Filteroperatorer

Operatør Beskrivelse Eksempel
eq Lig med { status: { eq: 'active' } }
ne Ikke ligeværdige { status: { ne: 'archived' } }
gt Større end { age: { gt: 18 } }
gte Større end eller lig med { age: { gte: 21 } }
lt Mindre end { price: { lt: 100 } }
lte Mindre end eller lig med { price: { lte: 50 } }
contains Indeholder delstreng { title: { contains: 'draft' } }

Sortér resultater

Brug orderBy() til at sortere forespørgselsresultater:

const notes = await client.data.Note.select([
  'id',
  'title',
  'createdAt',
])
  .orderBy({ createdAt: 'desc' })
  .execute();

Sorter efter flere kolonner:

const notes = await client.data.Note.select([
  'id',
  'title',
  'isPinned',
  'createdAt',
])
  .orderBy({ isPinned: 'desc' })
  .orderBy({ createdAt: 'desc' })
  .execute();

Når du definerer relationer med @one() og @many() decorators, kan du inkludere relaterede entitetsfelter i den samme forespørgsel:

const notes = await client.data.Note.select([
  'id',
  'title',
  'content',
  'notebook.id',
  'notebook.name',
  'notebook.color',
])
  .execute();

Hver note indeholder sine tilhørende notesbogsdata uden at kræve en separat forespørgsel.

Paginer-store resultatsæt

Brug cursorbaseret paginering til store lister:

const page = await client.data.Note.select([
  'id',
  'title',
  'createdAt',
])
  .orderBy({ createdAt: 'desc' })
  .first(25)
  .executePaginated();

console.log('Items:', page.items);
console.log('Has next page:', page.hasNextPage);
console.log('End cursor:', page.endCursor);

Hent næste side med cursoren:

if (page.hasNextPage) {
  const nextPage = await client.data.Note.select([
    'id',
    'title',
    'createdAt',
  ])
    .orderBy({ createdAt: 'desc' })
    .first(25)
    .after(page.endCursor)
    .executePaginated();
}

Bemærkning

Ejendommen totalCount vises på PagedResult typen, men er ikke fyldt af backend. Brug items.length den til at tælle resultater på den aktuelle side.

Opret poster

Brug create() metoden til at indsætte nye poster:

const newNote = await client.data.Note.create({
  title: 'Meeting notes',
  content: 'Discussion points from the team sync',
  isPinned: false,
  isArchived: false,
  createdAt: new Date(),
  updatedAt: new Date(),
  user_id: 'user-123',
});

Metoden returnerer den oprettede enhed med alle felter udfyldt, inklusive den autogenererede id.

Opret poster med relationer

Når du opretter enheder, der har relationer, skal enten det fulde relaterede objekt eller et objekt med kun primærnøglen blive sendt:

// Option 1: Pass just the ID
const note = await client.data.Note.create({
  title: 'Weekly summary',
  content: 'Summary of this week',
  notebook: { id: 'notebook-456' },
  isPinned: false,
  isArchived: false,
  createdAt: new Date(),
  updatedAt: new Date(),
});

// Option 2: Pass the full object
const notebook = await client.data.Notebook.findByPk('notebook-456');
const note = await client.data.Note.create({
  title: 'Weekly summary',
  content: 'Summary of this week',
  notebook: notebook,
  isPinned: false,
  isArchived: false,
  createdAt: new Date(),
  updatedAt: new Date(),
});

Begge former giver det samme resultat. Brug den første formular, når du allerede kender den relevante entitets ID og vil undgå en ekstra hent.

Opdateringsposter

Brug metoden update() til at ændre eksisterende poster. Send et filterobjekt og et objekt, der indeholder felterne, for at opdatere:

await client.data.Note.update(
  { id: 'note-123' },
  {
    title: 'Updated title',
    updatedAt: new Date(),
  }
);

Opdater relationer

For at ændre en relation, send den nye relaterede enhed eller blot dens ID:

// Move a note to a different notebook
await client.data.Note.update(
  { id: 'note-123' },
  { notebook: { id: 'new-notebook-789' } }
);

Slet poster

Brug metoden delete() til at fjerne poster, der matcher et filter:

await client.data.Note.delete({ id: 'note-123' });

Metoden løses, når backend bekræfter sletning. Hvis ingen poster matcher filteret, lykkes metoden stadig.

Håndter autentificering

Når autentificering er aktiveret, log ind før du udfører dataoperationer:

await client.auth.signIn({ email, password });

// All subsequent data calls include authentication context
const notes = await client.data.Note.select(['id', 'title']).execute();

Klienten tilknytter automatisk autentificeringssessionen til alle data-API-kald. Du behøver ikke at sende tokens manuelt.

Bedste praksis

  • Vælg kun nødvendige felter – Hent kun de felter, du bruger, for at reducere payload-størrelsen og forbedre ydeevnen.
  • Brug paginering til store lister – Undgå at hente tusindvis af poster på én gang ved at bruge first() og executePaginated().
  • Batch-relationsforespørgsler – Inkluder relaterede entitetsfelter i den samme forespørgsel i stedet for at lave separate anmodninger.
  • Cache ofte tilgåede data – Gem statiske referencedata i hukommelsen for at reducere API-kald.

Gældende begrænsninger

  • Metoden count() er ikke tilgængelig på den flydende klient. Vælg minimale felter og brug results.length i stedet.
  • Mange for mange relationer understøttes ikke. Brug en eksplicit join-enhed med to @one() navigationsdekoratorer.
  • Ejendommen totalCountPagedResult er ikke befolket af backend.