Oversigt over programmeringsmodellen

Rayfin SDK bruger en decorator-drevet programmeringsmodel, hvor du definerer dit dataskema én gang i TypeScript og automatisk modtager produktionsklare API'er, typesikre klienter og infrastruktur.

Nøglekoncepter

Rayfin SDK kombinerer tre kerneelementer:

  • Decorator-drevet skema: Brug TypeScript-decoratorer til at definere datamodeller, tilladelser og relationer.
  • Automatisk API-generering: Dine dekorerede klasser bliver GraphQL-endepunkter uden at skrive controller-kode.
  • Type-sikre klienter: Genererede TypeScript-klienter leverer kompileringsvalidering for forespørgsler og mutationer.

Sådan fungerer det

Når du opretter en Fabric-app, flyder din kode gennem disse faser:

# Fase Hvad sker der
1 Developer Du laver appen i din foretrukne editor.
2 TypeScript Du skriver entitetsklasser i TypeScript.
3 Dekoratører Du annoterer klasser og felter med @entity, @uuid, , @text, @roleog andre dekoratører.
4 Schema CLI'en kompilerer de dekorerede klasser til et databaseskema, tilladelsespolitikker og API-konfiguration.
5 API'er Skemaet offentliggøres som GraphQL-endpoints.
6 Klient Den genererede RayfinClient eksponerer en type-sikker data- og autentificeringsklient over disse endepunkter.
7 Applikation Din frontend-applikation bruger klienten til at læse og skrive data.

1. Definer datamodeller med dekoratorer

Du definerer din datastruktur ved hjælp af TypeScript-klasser og decoratorer fra @microsoft/rayfin-core:

import { entity, uuid, text, int } from '@microsoft/rayfin-core';

@entity()
export class Product {
  @uuid() id!: string;
  @text() name!: string;
  @text({ optional: true }) description?: string;
  @int() price!: number;
}

2. Skemagenerering

Rayfin CLI (npx rayfin) analyserer dine dekorerede klasser og genererer:

  • Databaseskema - Tabeller, kolonner, begrænsninger og indekser
  • API-konfiguration - GraphQL-endpointdefinitioner
  • Tilladelsespolitikker - Række-niveau sikkerhed og adgangskontrol på feltniveau

4. Type-sikker klientbrug

GraphQL API'er er tilgængelige for at udføre CRUD-operationer på din database. Rayfin SDK leverer en dataklientfunktion direkte til at læse, skrive eller slette data.

import { RayfinClient } from '@microsoft/rayfin-client';

const client = new RayfinClient();

// TypeScript knows about Product fields
const products = await client.data.products.query()
  .select(['id', 'name', 'price'])
  .execute();

// Compile-time error if field doesn't exist
const invalid = await client.data.products.query()
  .select(['nonexistentField'])  // ❌ TypeScript error
  .execute();

Dekorationsreference

Rayfin SDK leverer dekoratorer til almindelige datamodelleringsmønstre:

Entitetsdekoratører

Dekoratør Formål Eksempel
@entity() Markér en klasse som en databaseenhed @entity() class Product

Ejendomsdekoratører

Dekoratør Databasetype TypeScript-type
@uuid() UNIQUEIDENTIFIER string
@text() NVARCHAR string
@int() INT number
@decimal() DECIMAL number
@bool() BIT boolean
@date() DATETIME2 Date

Tilladelsesdekoratører

Dekoratør Formål
@role() Definér rollebaserede tilladelser

Se Definér datatilladelser for autorisationsdetaljer.

Functions

Opret én UserDataFunctions instans, og registrer hver funktion ved at kalde udf.func(name, handler, connections?).

Følg disse regler, når du definerer en funktion:

  • Placer parameteren hvor som RayfinContext helst i handlerens signatur. Kørselstiden identificerer den efter type, injicerer den og udelukker den fra de genererede funktionsinput.
  • Deklarér en forbindelse for hver delegeret token, som funktionen har brug for. Udelad forbindelsesarrayet for funktioner, der kun tilgår app-data eller ikke behøver delegerede tokens.

Følgende eksempel registrerer en almindelig funktion og en funktion, der bruger kaldelseskonteksten:

import {
  UserDataFunctions,
  type RayfinContext,
} from '@microsoft/fabric-user-data-functions';

// Match rayfin/data/schema.ts so getDataClient() is fully typed.
import type { TripPlan } from '../../data/TripPlan.js';

type AppSchema = { TripPlan: TripPlan };

const udf = new UserDataFunctions();

udf.func('greet', async (name: string): Promise<string> => {
  return `Hello, ${name}!`;
});

udf.func(
  'whoAmI',
  async (ctx: RayfinContext<AppSchema>): Promise<string> => {
    return ctx.accessToken ? 'authenticated' : 'anonymous';
  },
);

Den RayfinContext leverer funktionens runtime-tjenester:

Medlem Formål
ctx.accessToken Giver den indloggede brugers Rayfin JSON Web Token (JWT). Dekod kravet sub for at få et stabilt bruger-ID.
ctx.Tokens.<Audience> Får en platform-leveret ressourcetoken for et publikum, der er angivet i annotationen RayfinContext . Deployerede funktioner bruger appens identitet og dens tilladelser. For detaljer, se Forbind funktioner til eksterne ressourcer.
ctx.getSecret('NAME') Får en hemmelighed til den nuværende påkaldelse. Vender tilbage undefined , når hemmeligheden ikke er fastlagt.
ctx.getDataClient() Får typed data-API'en til dine enheder. Klienten understøtter oprettelse, findManyopdatering, slet og upsert-operationer.
ctx.baseUrl Giver Rayfin-endpointet for det aktuelle element.
ctx.publishableKey Giver den publicerbare nøgle til det aktuelle element.

For opsætning, lokal fejlfinding og udrulningsinstruktioner, se Brug funktioner i Fabric Apps.

Udviklingsarbejdsgang

En typisk udviklingscyklus følger dette mønster:

  1. Definer eller ændr datamodeller - Tilføj eller opdater TypeScript-klasser med decorators
  2. Test lokalt med remote backend - Kør npm run dev for at teste dine ændringer i frontend-koden mod din app-backend i Fabric.
  3. Deploy to Fabric - Kør npx rayfin up for at deploye til den managed Fabric-service og anvende dine skemaændringer.

Ændringer i dine TypeScript-modeller udbreder sig automatisk gennem hele stacken — fra databaseskema til API-endpoints til klienttyper.

Autorisation

Tilladelser defineres sammen med dine datamodeller ved hjælp af decoratoren @role :

@entity()
@role('authenticated', ['create', 'read', 'update', 'delete'], {
  policy: (claims, item) => claims.sub.eq(item.userId)
})
export class UserDocument {
  @uuid() id!: string;
  @text() userId!: string;
  @text() content!: string;
}

Denne tilgang sikrer:

  • Sikkerhedsregler ligger ved siden af de data, de beskytter
  • Type-sikre politikudtryk fanger fejl ved kompileringstid
  • Refaktorering af entitetsfelter opdaterer automatisk tilladelsestjek