Fabric Apps では、TypeScript デコレーターを使用して、データベース テーブルと API を生成するデータ モデルを定義します。 各エンティティは、 @entity()で修飾されたクラスとして定義し、データ型のフィールド デコレーターを追加し、エンティティ間のリレーションシップをマップします。
承認とアクセス制御のガイダンスについては、「 データのアクセス許可の定義」を参照してください。
前提条件
-
npm create @microsoft/rayfin@latestで作成されるか、npx rayfin initで初期化されたFabric Apps プロジェクト。 - TypeScript クラスとデコレーターの基本的な理解。
エンティティを定義する
データ モデルを作成するには、typeScript クラスに @entity() デコレーターを追加します。 次に、必要なデコレーターを @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;
}
このエンティティは、Todo、id、title、description、およびcreatedAtの列を含むupdatedAt テーブルを生成します。
主キー
すべてのエンティティは、主キーとして string という UUID id フィールドを使用します。
id を明示的に宣言しない場合は、Fabric Apps によってスキーマに自動的に追加されます。
-
idフィールドは、作成操作中は省略可能です。このフィールドを省略すると、サーバーによって UUID が生成されます。 - クライアントによって生成される識別子を使用する場合は、作成時に独自の UUID を指定できます。
- 複合主キーとカスタム キー名はサポートされていません。
@entity()
export class Note {
@uuid() id!: string; // UUID primary key, auto-generated when omitted
@text() title!: string;
@text() content!: string;
}
サポートされているデータの種類
フィールド型を定義するには、次のデコレーターを使用します。
| デコレーター | タイプ | 説明 |
|---|---|---|
@uuid() |
文字列 | 一意の識別子フィールド |
@text() |
文字列 | 省略可能な長さの制約を持つテキスト フィールド。 |
@int() |
数値 | 整数フィールド。 |
@decimal() |
数値 | 10進数フィールドまたは数値フィールド。 |
@boolean() |
boolean | True または false フィールド。 |
@date() |
Date | 日付と時刻フィールド。ISO 文字列または Date オブジェクトからシリアル化されます。 |
@email() |
文字列 | 電子メールの検証を含むテキスト フィールド。 |
@set() |
文字列 | 文字列リテラルの列挙されたセット。 |
複数の型を含む例
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';
}
型修飾子
フィールド デコレーターに修飾子を追加して、検証と制約を構成します。
| 修飾子 | 説明 |
|---|---|
{ optional: true } |
NULL 値を許可します。 フィールドは既定で必須です。 |
{ unique: true } |
一意制約を追加します。 |
{ default: value } |
既定値の式を設定します。 |
{ max: n }、{ min: n } |
文字列の長さの制約 (最大文字数と最小文字数)。 |
{ min: n }、{ max: n } |
数値制約。 |
Note
TypeScript の省略可能なマーカー (プロパティ名の後に? ) は、静的な TypeScript 型にのみ影響します。 データベース列を null 値にすることはできません。 フィールドを null 許容にするには、デコレーターに { optional: true } を追加します。
!を使用して、必要なフィールドがフレームワークによって初期化されていることをアサートします。
修飾子を使用した例
@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;
}
リレーションシップを定義する
@one()および@many()デコレーターを使用して、エンティティ間のナビゲーション プロパティを定義します。 Fabric Apps では、リレーションシップを定義すると外部キー列が自動生成されます。
-
一対多 – 親に
@many()を使用し、子に@one()します。 -
多対一 – 子側で
@one()を使用して親を参照します。 - 多対多リレーションシップはサポートされていません。代わりに明示的な結合エンティティを使用してください。
一対多リレーションシップの例
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;
}
@one(() => Notebook) エンティティで Note を定義すると、Fabric Apps によって外部キー列notebook_id が自動的に作成されます。 外部キー フィールドは、アプリケーション コードで読み取りまたは設定する場合にのみ明示的に宣言します。
外部キーの名前付け規則
外部キー フィールドを定義する場合は、 {property}_id 名前付け規則を使用します。
@entity()
export class Note {
@uuid() id!: string;
@text() notebook_id!: string; // Foreign key field
@one(() => Notebook) notebook?: Notebook; // Navigation property
}
カスタム外部キー名 (foreignKey、 targetKey オプション) はサポートされていません。
参照システム エンティティ
Fabric Apps では、組み込みの @one() エンティティなどのシステム エンティティを指す USER リレーションシップはサポートされていません。 サインインしているユーザーに行を関連付けるには、user_id型のプレーンな@text() フィールドを追加し、認証要求 (通常はclaims.sub) から設定します。
@entity()
export class Task {
@uuid() id!: string;
@text() title!: string;
@text() user_id!: string; // System user ID from claims.sub
}
ロール ポリシーの user_id で行をフィルター処理して、ユーザーごとのアクセスを強制します。
スキーマにエンティティを登録する
クライアントが GraphQL プロキシを生成できるように、すべてのエンティティ クラスを rayfin/data/schema.ts に追加します。
import type { Note } from './Note.js';
import type { Notebook } from './Notebook.js';
export type NotesAppSchema = {
Note: Note;
Notebook: Notebook;
};
新しいエンティティを作成するたびに、この型を更新します。
スキーマの変更を適用する
エンティティを定義または変更した後、データベースに変更を適用します。
更新されたスキーマをFabricにデプロイします。
npx rayfin up db applyスキーマの変更に破壊的操作 (列の削除、テーブルの名前変更) が含まれている場合、CLI によって警告が表示され、続行は拒否されます。
--forceを使用して、安全性チェックをオーバーライドします。npx rayfin up db apply --force
Note
--forceを使用すると、データが失われる可能性があります。 続行する前に、一覧表示されている操作を注意深く確認してください。
ベスト プラクティス
- 外部キー フィールドは、コードで読み取りまたは設定する必要がある場合にのみ定義します。Fabric Apps では、ナビゲーション デコレーターから自動的に生成されます。
- 生成された ESM JavaScript が正しく解決されるように、エンティティ ファイル内の
.js拡張機能で相対インポートを使用します。 - 承認パターンとロールベースのアクセスについては、「データアクセス 許可の定義」を参照してください。
Troubleshooting
リレーションシップが見つからない
API にリレーションシップが表示されない場合は、次のことを確認します。
- ナビゲーション デコレーター (
@one()または@many()) が存在します。 - エンティティは
rayfin/data/schema.tsに登録されます。