Definieren von Datenmodellen für Fabric Apps

Fabric Apps verwendet TypeScript-Dekoratoren zum Definieren von Datenmodellen, die Datenbanktabellen und APIs generieren. Sie definieren jede Entität als Klasse, die mit @entity()versehen ist, Fügen Sie Felddekortoren für Datentypen hinzu und ordnen Sie Beziehungen zwischen Entitäten zu.

Anweisungen zur Autorisierung und Zugriffssteuerung finden Sie unter Definieren von Datenberechtigungen.

Voraussetzungen

  • Ein Fabric Apps-Projekt, das mit npm create @microsoft/rayfin@latest erstellt oder mit npx rayfin init initialisiert wurde.
  • Grundlegendes Verständnis von TypeScript-Klassen und Dekorateuren.

Definieren einer Entität

Um ein Datenmodell zu erstellen, fügen Sie den @entity() Dekorateur einer TypeScript-Klasse hinzu. Importieren Sie dann die erforderlichen Dekoratoren aus @microsoft/rayfin-core:

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

@entity()
export class Todo {
  @uuid() id!: string;
  @text() title!: string;
  @text({ optional: true }) description?: string;
  @date() createdAt!: Date;
  @date() updatedAt!: Date;
}

Diese Entität generiert eine Todo Tabelle mit Spalten für id, title, , description, createdAtund updatedAt.

Primärschlüssel

Jede Entität verwendet ein UUID-Feld string , das als Primärschlüssel bezeichnet wird id . Wenn Sie id nicht explizit deklarieren, fügt Fabric Apps es dem Schema automatisch hinzu.

  • Das id Feld ist bei Erstellungsvorgängen optional – der Server generiert eine UUID, wenn Sie es weglassen.
  • Sie können bei der Erstellung Ihre eigene UUID angeben, wenn Sie clientseitig generierte Bezeichner bevorzugen.
  • Zusammengesetzte Primärschlüssel und benutzerdefinierte Schlüsselnamen werden nicht unterstützt.
@entity()
export class Note {
  @uuid() id!: string;  // UUID primary key, auto-generated when omitted
  @text() title!: string;
  @text() content!: string;
}

Unterstützte Datentypen

Verwenden Sie diese Dekoratoren, um Feldtypen zu definieren:

Dekorateur Typ Description
@uuid() Schnur Feld für eindeutige Kennung.
@text() Schnur Textfeld mit optionalen Längeneinschränkungen.
@int() Zahl Ganzzahliges Feld.
@decimal() Zahl Dezimal- oder numerisches Feld.
@boolean() Boolescher Wert True- oder False-Feld.
@date() Date Datums- und Uhrzeitfeld, serialisiert aus ISO-Zeichenfolgen oder Date -Objekten.
@email() Schnur Textfeld mit E-Mail-Überprüfung.
@set() Schnur Aufzählung von String-Literalen.

Beispiel mit mehreren Typen

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

@entity()
export class Product {
  @uuid() id!: string;
  @text() name!: string;
  @decimal() price!: number;
  @int() stockQuantity!: number;
  @boolean() isAvailable!: boolean;
  @date() createdAt!: Date;
  @set('draft', 'published', 'archived') status!: 'draft' | 'published' | 'archived';
}

Typmodifizierer

Fügen Sie Felddekoratoren Modifizierer hinzu, um Validierungen und Einschränkungen zu konfigurieren:

Modifizierer Description
{ optional: true } Lässt NULL-Werte zu. Felder sind standardmäßig erforderlich.
{ unique: true } Fügen Sie eine eindeutige Einschränkung hinzu.
{ default: value } Legen Sie einen Standardwertausdruck fest.
{ max: n }, { min: n } Zeichenfolgenlängeneinschränkungen (maximale und minimale Anzahl von Zeichen).
{ min: n }, { max: n } Einschränkungen für numerische Werte.

Hinweis

Die optionale TypeScript-Markierung (? nach einem Eigenschaftsnamen) wirkt sich nur auf den statischen TypeScript-Typ aus. Dadurch wird die Datenbankspalte nicht NULL-fähig. Um ein Feld als nullable zu kennzeichnen, fügen Sie { optional: true } zum Decorator hinzu. Wird ! verwendet, um zu bestätigen, dass ein erforderliches Feld vom Framework initialisiert wird.

Beispiel mit Modifizierern

@entity()
export class User {
  @uuid() id!: string;
  @email({ unique: true }) email!: string;
  @text({ min: 3, max: 50 }) username!: string;
  @text({ optional: true, max: 500 }) bio?: string;
  @int({ min: 0, max: 150 }) age!: number;
  @boolean({ default: false }) isVerified!: boolean;
}

Definieren von Beziehungen

Verwenden Sie die Dekoratoren @one() und @many(), um Navigationseigenschaften zwischen Entitäten zu definieren. Fabric Apps generiert automatisch Fremdschlüsselspalten, wenn Sie Beziehungen definieren.

  • 1:n – Wird für das Übergeordnete und @many() das Kind verwendet@one().
  • Viele-zu-eins – Verwenden Sie @one() für das untergeordnete Element, um auf das übergeordnete Element zu verweisen.
  • Viele-zu-viele-Beziehungen werden nicht unterstützt – verwenden Sie stattdessen eine explizite Verknüpfungsentität.

Beispiel für 1:n-Beziehung

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

@entity()
export class Notebook {
  @uuid() id!: string;
  @text() name!: string;
  @date() createdAt!: Date;
  @many(() => Note) notes?: Note[];
}

@entity()
export class Note {
  @uuid() id!: string;
  @text() title!: string;
  @text() content!: string;
  @date() createdAt!: Date;
  @text() notebook_id!: string;
  @one(() => Notebook) notebook?: Notebook;
}

Wenn Sie @one(() => Notebook) für die Entität Note definieren, erstellt Fabric Apps automatisch eine notebook_id Fremdschlüsselspalte. Deklarieren Sie das Fremdschlüsselfeld explizit nur, wenn Sie beabsichtigen, es im Anwendungscode zu lesen oder festzulegen.

Benennungskonvention für Fremdschlüssel

Wenn Sie ein Fremdschlüsselfeld definieren, verwenden Sie die {property}_id Benennungskonvention:

@entity()
export class Note {
  @uuid() id!: string;
  @text() notebook_id!: string;      // Foreign key field
  @one(() => Notebook) notebook?: Notebook;  // Navigation property
}

Benutzerdefinierte Fremdschlüsselnamen (foreignKey, targetKey Optionen) werden nicht unterstützt.

Referenzsystementitäten

Fabric Apps unterstützt keine @one() Beziehungen, die auf Systementitäten verweisen, z. B. die integrierte USER-Entität. Um dem angemeldeten Benutzer eine Zeile zuzuordnen, fügen Sie ein einfaches user_id Feld vom Typ @text() hinzu und füllen Sie sie aus den Authentifizierungsansprüchen auf (in der Regel claims.sub):

@entity()
export class Task {
  @uuid() id!: string;
  @text() title!: string;
  @text() user_id!: string;  // System user ID from claims.sub
}

Filtern Sie Zeilen mithilfe von user_id in Ihren Rollenrichtlinien, um benutzerspezifischen Zugriff zu erzwingen.

Registrieren von Entitäten im Schema

Fügen Sie alle Entitätsklassen hinzu rayfin/data/schema.ts , damit der Client GraphQL-Proxys generieren kann:

import type { Note } from './Note.js';
import type { Notebook } from './Notebook.js';

export type NotesAppSchema = {
  Note: Note;
  Notebook: Notebook;
};

Aktualisieren Sie diesen Typ immer dann, wenn Sie eine neue Entität erstellen.

Schemaänderungen anwenden

Nach der Definition oder Änderung der Entitäten wenden Sie die Änderungen in der Datenbank an. Für den vollständigen Bereitstellungs- und Verifikationsworkflow siehe Schemaänderungen anwenden und verifizieren.

  1. Stellen Sie das aktualisierte Schema für Fabric bereit:

    npx rayfin up db apply
    
  2. Wenn die Schemaänderung destruktive Vorgänge (Ablegen von Spalten, Umbenennen von Tabellen) enthält, warnt Sie die CLI und lehnt den Vorgang ab. Verwenden Sie --force diese Option, um die Sicherheitsüberprüfung außer Kraft zu setzen:

    npx rayfin up db apply --force
    

Hinweis

Die Verwendung --force kann zu Datenverlust führen. Überprüfen Sie die aufgelisteten Vorgänge sorgfältig, bevor Sie fortfahren.

Bewährte Methoden

  • Definieren Sie Fremdschlüsselfelder nur, wenn Sie sie im Code lesen oder setzen müssen – Fabric Apps generiert sie automatisch aus Navigations-Decorators.
  • Verwenden Sie relative Importe mit .js Erweiterungen in Entitätsdateien, damit das ausgegebene ESM-JavaScript ordnungsgemäß aufgelöst wird.
  • Informationen zu Autorisierungsmustern und rollenbasiertem Zugriff finden Sie unter Definieren von Datenberechtigungen.

Troubleshooting

Fehlende Beziehungen

Wenn Beziehungen nicht in der API angezeigt werden, überprüfen Sie Folgendes:

  • Der Navigationsdekorator (@one() oder @many()) ist vorhanden.
  • Die Entität ist registriert in rayfin/data/schema.ts.