Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Fabric Apps utilise des décorateurs TypeScript pour définir des modèles de données qui génèrent des tables de base de données et des API. Vous définissez chaque entité en tant que classe décorée avec @entity(), ajoutez des décorateurs de champs pour les types de données et mappez les relations entre les entités.
Pour obtenir des conseils sur le contrôle d’autorisation et d’accès, consultez Définir des autorisations de données.
Prerequisites
- Projet Fabric Apps créé avec
npm create @microsoft/rayfin@latestou initialisé avecnpx rayfin init. - Compréhension de base des classes et des décorateurs TypeScript.
Définir une entité
Le modèle par défaut blankapp crée un espace de travail d’application universelle avec les données désactivées. Activez-le avec la capacité de modélisation des données du modèle :
npm run pack:add -- data-modeling
Cette étape ajoute une entité Starter et un contrat partagé. Inscrivez les classes d’entité dans packages/data/src/, enregistrez-les dans packages/data/src/index.ts, et maintenez leurs contrats destinés aux clients dans packages/shared/src/index.ts. Le service de données utilise services.data.path: packages/data dans rayfin/rayfin.yml. Lorsque vous configurez manuellement Data pour Fabric, réglez enabled: true également et dialect: mssql.
Les modèles plats peuvent plutôt conserver les entités dans rayfin/data/ et utiliser rayfin/data/schema.ts. Suivez vos chemins de service configurés plutôt que de créer un second dossier de données. Voir structure du projet.
Pour créer un modèle de données, ajoutez le @entity() décorateur à une classe TypeScript. Ensuite, importez les décorateurs requis à partir de @microsoft/rayfin-core:
import { entity, uuid, text, date } from '@microsoft/rayfin-core';
@entity()
export class Todo {
@uuid() id!: string;
@text({ max: 200 }) title!: string;
@text({ optional: true, max: 2000 }) description?: string;
@date() createdAt!: Date;
@date() updatedAt!: Date;
}
Cette entité génère une Todo table avec des colonnes pour id, , titledescription, , createdAtet updatedAt.
Important
Attribuez aux champs de texte persistants une longueur maximale explicite adaptée à vos données. Sur Microsoft SQL Server, le texte sans max engendre NVARCHAR(MAX), ce qui peut empêcher la génération de métadonnées GraphQL. Les exemples utilisent du texte délimité, incluant les chaînes de propriétaires et de clés étrangères. Voir Résoudre les problèmes liés au modèle de données.
Clés primaires
Chaque entité utilise un champ UUID string nommé id comme clé primaire. Si vous ne déclarez pas id explicitement, Fabric Apps l'ajoute automatiquement au schéma.
- Le
idchamp est facultatif pendant les opérations de création : le serveur génère un UUID si vous l’omettez. - Vous pouvez fournir votre propre UUID au moment de la création si vous préférez les identificateurs générés par le client.
- Les clés primaires composites et les noms de clés personnalisés ne sont pas pris en charge.
@entity()
export class Note {
@uuid() id!: string; // UUID primary key, auto-generated when omitted
@text({ max: 200 }) title!: string;
@text({ max: 4000 }) content!: string;
}
Types de données prises en charge
Utilisez ces décorateurs pour définir des types de champs :
| Décorateur | Type | Description |
|---|---|---|
@uuid() |
string | Champ Identificateur unique. |
@text({ max: n }) |
string | Champ texte avec une longueur maximale explicite pour les colonnes MSSQL persistantes. |
@int() |
Numéro | Champ de type entier. |
@decimal() |
Numéro | Champ décimal ou numérique. |
@boolean() |
booléen | Champ True ou false. |
@date() |
Date | Champ de date et d’heure, se sérialise depuis des chaînes ISO ou des objets Date. |
@email() |
string | Champ texte avec validation par e-mail. |
@set() |
string | Ensemble de littéraux de type chaîne de caractères énumérés. |
Exemple avec plusieurs types
import { entity, uuid, text, int, decimal, boolean, date, set } from '@microsoft/rayfin-core';
@entity()
export class Product {
@uuid() id!: string;
@text({ max: 200 }) name!: string;
@decimal() price!: number;
@int() stockQuantity!: number;
@boolean() isAvailable!: boolean;
@date() createdAt!: Date;
@set('draft', 'published', 'archived') status!: 'draft' | 'published' | 'archived';
}
Modificateurs de type
Ajoutez des modificateurs aux décorateurs de champs pour configurer la validation et les contraintes :
| Modificateur | Description |
|---|---|
{ optional: true } |
Autoriser les valeurs NULL. Les champs sont obligatoires par défaut. |
{ unique: true } |
Ajoutez une contrainte unique. |
{ default: value } |
Définissez une expression de valeur par défaut. |
{ max: n }, { min: n } |
Contraintes de longueur de chaîne (nombre maximal et minimal de caractères). |
{ min: n }, { max: n } |
Contraintes de valeur numérique. |
Note
Le marqueur facultatif TypeScript (? après un nom de propriété) affecte uniquement le type TypeScript statique. Elle ne rend pas la colonne de base de données nullable. Pour rendre un champ nullable, ajoutez { optional: true } à l’élément décoratif. Utilisez ! pour indiquer qu’un champ obligatoire est initialisé par le framework.
Exemple avec des modificateurs
@entity()
export class User {
@uuid() id!: string;
@email({ unique: true, max: 254 }) 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;
}
Définir des relations
Utilisez les décorateurs @one() et @many() pour définir les propriétés de navigation entre les entités. Fabric Apps génère automatiquement des colonnes clés étrangères lorsque vous définissez des relations.
-
Un-à-plusieurs : utiliser
@many()sur le parent et@one()sur l’enfant. -
Plusieurs-à-un : utiliser
@one()sur l’enfant pour référencer le parent. - Les relations plusieurs-à-plusieurs ne sont pas prises en charge : utilisez plutôt une entité de jointure explicite.
Exemple avec une relation un-à-plusieurs
import { entity, uuid, text, date, one, many } from '@microsoft/rayfin-core';
@entity()
export class Notebook {
@uuid() id!: string;
@text({ max: 200 }) name!: string;
@date() createdAt!: Date;
@many(() => Note) notes?: Note[];
}
@entity()
export class Note {
@uuid() id!: string;
@text({ max: 200 }) title!: string;
@text({ max: 4000 }) content!: string;
@date() createdAt!: Date;
@text({ max: 36 }) notebook_id!: string;
@one(() => Notebook) notebook?: Notebook;
}
Lorsque vous définissez @one(() => Notebook) sur l’entité Note, Fabric Apps crée automatiquement une colonne de clé étrangère notebook_id. Déclarez explicitement le champ de clé étrangère uniquement si vous envisagez de le lire ou de le définir dans le code de l’application.
Convention d’affectation de noms de clé étrangère
Lorsque vous définissez un champ de clé étrangère, utilisez la convention d’affectation {property}_id de noms :
@entity()
export class Note {
@uuid() id!: string;
@text({ max: 36 }) notebook_id!: string; // Foreign key field
@one(() => Notebook) notebook?: Notebook; // Navigation property
}
Les noms personnalisés de clés étrangères (foreignKey, targetKey options) ne sont pas pris en charge.
Entités système de référence
Fabric Apps ne prend pas en charge les relations @one() qui pointent vers des entités système telles que l'entité intégrée USER. Pour associer une ligne à l’utilisateur connecté, ajoutez un champ de texte borné user_id et remplissez-le à partir des claims d’authentification (généralement claims.sub) :
@entity()
export class Task {
@uuid() id!: string;
@text({ max: 200 }) title!: string;
@text({ max: 255 }) user_id!: string; // System user ID from claims.sub
}
Filtrez les lignes en fonction de user_id dans vos stratégies de rôle pour appliquer un contrôle d’accès par utilisateur.
Inscrire des entités dans le schéma
Dans un espace de travail Universal App, enregistrez les classes d’entités d’exécution dans packages/data/src/index.ts:
import { Note } from './Note.js';
import { Notebook } from './Notebook.js';
export const schema = [Note, Notebook];
Gardez les interfaces d’enregistrement correspondantes et le mappage UniversalAppSchema dans packages/shared/src/index.ts alignés avec ces entités. Le frontend importe UniversalAppSchema depuis @rayfin-app/shared; il n’importe pas les classes d’exécution décorées. Ajoutez Product aux deux enregistrements si vous utilisez les exemples d’agrégation numérique dans Lire et écrire des données.
Pour une alternative à modèle plat, mappez les types d’entité dans rayfin/data/schema.ts :
import type { Note } from './Note.js';
import type { Notebook } from './Notebook.js';
export type NotesAppSchema = {
Note: Note;
Notebook: Notebook;
};
Mettez à jour les enregistrements et types de schémas pour la mise en page choisie chaque fois que vous créez une nouvelle entité.
Appliquer les modifications de schéma
Après avoir défini ou modifié les entités, appliquez les modifications à la base de données. Pour le flux de déploiement complet et de vérification, voir Appliquer et vérifier les modifications de schéma.
Déployez le schéma mis à jour sur Fabric :
npx rayfin up db applySi le changement de schéma inclut des opérations destructrices (suppression de colonnes, renommage des tables), l’interface CLI vous avertit et refuse de continuer. Permet
--forcede remplacer le contrôle de sécurité :npx rayfin up db apply --force
Note
L’utilisation --force peut entraîner une perte de données. Passez en revue attentivement les opérations répertoriées avant de continuer.
Bonnes pratiques
- Définissez les champs de clé étrangère uniquement lorsque vous devez les lire ou les définir dans le code, Fabric Apps les génère automatiquement à partir de décorateurs de navigation.
- Utilisez des importations relatives avec les extensions
.jsdans les fichiers d’entité pour que le JavaScript ESM généré soit correctement résolu. - Pour connaître les modèles d’autorisation et l’accès en fonction du rôle, consultez Définir des autorisations de données.
Résolution des problèmes
Relations manquantes
Si les relations n’apparaissent pas dans l’API, vérifiez que :
- Le décorateur de navigation (
@one()ou@many()) est présent. - L’entité est enregistrée dans votre package de données configuré et votre schéma partagé, ou dans
rayfin/data/schema.tspour un modèle plat.