程式模型概述

Rayfin SDK 採用裝飾者驅動的程式設計模型,只要在 TypeScript 中定義資料結構,就能自動收到生產環境可用的 API、型別安全用戶端和基礎設施。

關鍵概念

Rayfin SDK 結合了三個核心元素:

  • 裝飾器驅動的架構:使用 TypeScript 裝飾器來定義資料模型、權限與關聯。
  • 自動 API 產生:你裝飾好的類別會變成 GraphQL 端點,無需撰寫控制器程式碼。
  • 型別安全的用戶端:產生的 TypeScript 用戶端可為查詢與變更提供編譯時驗證。

運作原理

當你建立 Fabric 應用程式時,程式碼會經歷以下幾個階段:

# Stage 會發生什麼事
1 開發人員 你可以在你選擇的編輯器中撰寫應用程式。
2 TypeScript 你可以用 TypeScript 來寫實體類別。
3 Decorators 你會使用 @entity@uuid@text@role 和其他裝飾器來為類別和欄位加上註解。
4 Schema CLI 會將裝飾好的類別編譯成資料庫架構、權限政策及 API 設定。
5 應用程式介面(API) 該結構以 GraphQL 端點形式發佈。
6 Client 產生的 RayfinClient 會透過這些端點提供具型別安全的資料與驗證用戶端。
7 應用程式 你的前端應用程式會消耗用戶端來讀寫資料。

1. 定義帶有裝飾器的資料模型

你可以使用 TypeScript 類別和裝飾器 @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. 結構產生

Rayfin CLI(npx rayfin)會分析你裝飾的類別並產生:

  • 資料庫結構 - 表格、欄位、約束與索引
  • API 設定 - GraphQL 端點定義
  • 權限政策 - 列級安全與現場層級存取控制

4. 型別安全的客戶端用法

GraphQL API 可用於對你的資料庫執行 CRUD 操作。 Rayfin SDK 開箱即用,提供可用於讀取、寫入或刪除資料的資料用戶端作業。

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

裝飾師參考

Rayfin SDK 提供常見資料建模模式的裝飾工具:

實體裝飾器

裝飾項目 Purpose Example
@entity() 將類別標記為資料庫實體 @entity() class Product

物業裝飾師

裝飾項目 資料庫類型 TypeScript 類型
@uuid() UNIQUEIDENTIFIER string
@text() NVARCHAR string
@int() INT number
@decimal() DECIMAL number
@bool() 比特 boolean
@date() DATETIME2 Date

許可裝飾師

裝飾項目 Purpose
@role() 定義基於角色的權限

請參閱 定義資料權限 以了解授權細節。

開發工作流程

典型的開發流程遵循以下模式:

  1. 定義或修改資料模型 - 新增或更新帶有裝飾器的 TypeScript 類別
  2. 在本機搭配遠端後端進行測試 - 執行 npm run dev,以根據 Fabric 中的 App 後端測試前端程式碼變更。
  3. Deploy to Fabric - 執行 npx rayfin up 部署到託管的 Fabric 服務,並套用你的結構變更。

TypeScript 模型的變更會自動在整個堆疊中傳播——從資料庫架構到 API 端點再到用戶端類型。

Authorization

權限會使用 @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;
}

此方法可確保:

  • 安全規則存在於它們所保護的資料旁邊
  • 型別安全政策表達式會在編譯時捕捉錯誤
  • 重構實體欄位會自動更新權限檢查