Panoramica del modello di programmazione

Rayfin SDK usa un modello di programmazione guidato da decoratori in cui definisci lo schema dei dati una sola volta in TypeScript e ricevi automaticamente API pronte per la produzione, client con sicurezza di tipo e l'infrastruttura.

Concetti chiave

Rayfin SDK combina tre elementi principali:

  • Schema guidato dai decoratori: Usa i decoratori TypeScript per definire modelli di dati, autorizzazioni e relazioni.
  • Generazione automatica dell'API: le classi decorate diventano endpoint GraphQL senza scrivere codice controller.
  • Client con controllo dei tipi: i client TypeScript generati offrono la convalida in fase di compilazione per query e modifiche.

Come funziona

Quando si crea un'app Fabric, il codice passa attraverso queste fasi:

# Stage Che succede
1 Developer L'app viene creata nell'editor preferito.
2 TypeScript Le classi di entità sono scritte in TypeScript.
3 Decorators Si annotano classi e campi con @entity, @uuid, @text, @role e altri decoratori.
4 Schema L'interfaccia della riga di comando compila le classi decorate in uno schema di database, criteri di autorizzazione e configurazione API.
5 API (Interfaccia di Programmazione delle Applicazioni) Lo schema è pubblicato come endpoint GraphQL.
6 Client L'elemento generato RayfinClient espone un client per dati e autenticazione con sicurezza di tipo tramite quegli endpoint.
7 Applicazione L'applicazione front-end usa il client per leggere e scrivere dati.

1. Definire modelli di dati con i decorator

Definisci la struttura dei dati utilizzando classi TypeScript e decoratori da @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. Generazione dello schema

La CLI di Rayfin (npx rayfin) analizza le classi decorate e genera:

  • Schema del database - Tabelle, colonne, vincoli e indici
  • Configurazione dell'API - Definizioni di endpoint GraphQL
  • Criteri di autorizzazione - Sicurezza a livello di riga e controllo di accesso a livello di campo

4. Utilizzo del client con controllo dei tipi

Le API GraphQL sono disponibili per eseguire operazioni CRUD nel database. Rayfin SDK fornisce pronta all'uso un'operazione client per i dati per leggere, scrivere o eliminare dati.

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();

Informazioni di riferimento su Decorator

Rayfin SDK fornisce decoratori per schemi comuni di modellazione dei dati:

Decoratori di entità

Decoratore Purpose Example
@entity() Contrassegnare una classe come entità di database @entity() class Product

Decoratori di proprietà

Decoratore Tipo di database Tipo TypeScript
@uuid() UNIQUEIDENTIFIER string
@text() NVARCHAR string
@int() INT number
@decimal() DECIMALE number
@bool() BIT boolean
@date() DATETIME2 Date

Decoratori dei permessi

Decoratore Purpose
@role() Definire le autorizzazioni basate sui ruoli

Per informazioni dettagliate sull'autorizzazione, vedere Definire le autorizzazioni per i dati .

Functions

Crea un'istanza UserDataFunctions e registra ogni funzione chiamando udf.func(name, handler, connections?).

Segui queste regole quando definisci una funzione:

  • Posiziona il parametro RayfinContext ovunque nella firma del gestore. Il runtime lo identifica per tipo, lo inietta ed esclude dagli input delle funzioni generate.
  • Dichiara una connessione per ogni token delegato di cui la funzione ha bisogno. Ometti l'array delle connessioni per le funzioni che accedono solo ai dati dell'app o non hanno bisogno di token delegati.

Il seguente esempio registra una funzione semplice e una funzione che utilizza il contesto di invocazione:

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';
  },
);

RayfinContext fornisce i servizi di runtime della funzione:

Membro Purpose
ctx.accessToken Fornisce il Rayfin JSON Web Token (JWT) dell'utente loginato. Decodifica la sub richiesta per ottenere un ID utente stabile.
ctx.Tokens.<Audience> Riceve un token di risorsa fornito dalla piattaforma per un pubblico dichiarato nell'annotazione RayfinContext . Le Funzioni Distribuite utilizzano l'identità dell'app e i suoi permessi. Per dettagli, vedi Collega Funzioni a risorse esterne.
ctx.getSecret('NAME') Ottiene un segreto per l'invocazione attuale. Ritorna undefined quando il segreto non è stato stabilito.
ctx.getDataClient() Ottiene l'API dei dati tipati per le tue entità. Il client supporta le operazioni di creazione, findManyaggiornamento, eliminazione e upsert.
ctx.baseUrl Fornisce l'endpoint Rayfin per l'elemento corrente.
ctx.publishableKey Fornisce la chiave pubblicabile per l'oggetto corrente.

Per configurazione, debug locale e istruzioni di implementazione, consulta Usa Funzioni nelle app Fabric.

Flusso di lavoro per lo sviluppo

Un ciclo di sviluppo tipico segue questo modello:

  1. Definire o modificare i modelli di dati - Aggiungere o aggiornare classi TypeScript con elementi Decorator
  2. Esegui test in locale con backend remoto - Esegui npm run dev per testare le modifiche al codice frontend con il backend dell'app in Fabric.
  3. Distribuisci in Fabric - Esegui npx rayfin up per distribuire nel servizio Fabric gestito e applicare le modifiche allo schema.

Le modifiche apportate ai modelli TypeScript vengono propagate automaticamente nell'intero stack, dallo schema del database agli endpoint API ai tipi di client.

Authorization

Le autorizzazioni vengono definite insieme ai modelli di dati utilizzando il decoratore @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;
}

Questo approccio garantisce:

  • Le regole di sicurezza si trovano accanto ai dati che proteggono
  • Le espressioni di criteri con controllo dei tipi intercettano gli errori in fase di compilazione
  • Il refactoring dei campi dell'entità aggiorna automaticamente i controlli delle autorizzazioni