程式模型概述

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() 定義基於角色的權限

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

Functions

建立一個 UserDataFunctions 實例,並透過呼叫 udf.func(name, handler, connections?)註冊每個函式。

定義函數時請遵循以下規則:

  • 將 RayfinContext 參數放在處理常式簽章中的任何位置。 執行時會依類型識別它,注入它,並將它排除在產生的函式輸入中。
  • 為函式所需的每個委派標記宣告一個連線。 對於只存取應用程式資料或不需要委託令牌的函式,省略連接陣列。

以下範例註冊了一個純函數,一個使用呼叫上下文的函式:

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 提供函式的執行時服務:

會員 Purpose
ctx.accessToken 提供登入使用者的 Rayfin JSON 網頁令牌(JWT)。 解碼這個 sub 說法,取得穩定的使用者ID。
ctx.Tokens.<Audience> 會獲得標註中 RayfinContext 宣告的受眾平台提供的資源代幣。 部署功能使用應用程式的身份及其權限。 詳情請參見 「連接函式與外部資源」。
ctx.getSecret('NAME') 取得目前叫用的密鑰。 當秘密未設定時會回來 undefined 。
ctx.getDataClient() 取得供你的實體使用的型別資料 API。 用戶端支援建立、 findMany更新、刪除及上傳訊息等操作。
ctx.baseUrl 提供當前項目的 Rayfin 端點。
ctx.publishableKey 提供當前項目的可發佈金鑰。

關於設定、本地除錯及部署說明,請參見「在 Fabric 應用程式中使用函式」。

開發工作流程

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

  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;
}

此方法可確保:

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