ภาพรวมโมเดลการเขียนโปรแกรม

Rayfin SDK ใช้โมเดลการเขียนโปรแกรมที่ขับเคลื่อนด้วยตัวตกแต่ง ซึ่งคุณกําหนดสคีมาข้อมูลของคุณเพียงครั้งเดียวใน TypeScript และรับ API ที่พร้อมใช้งานจริง ไคลเอ็นต์ที่ปลอดภัยประเภท และโครงสร้างพื้นฐานโดยอัตโนมัติ

แนวคิดหลัก

Rayfin SDK รวมองค์ประกอบหลักสามประการ:

  • สคีมาที่ขับเคลื่อนด้วยตัวตกแต่ง: ใช้ตัวตกแต่ง TypeScript เพื่อกําหนดแบบจําลองข้อมูล สิทธิ์ และความสัมพันธ์
  • การสร้าง API อัตโนมัติ: คลาสที่ตกแต่งของคุณจะกลายเป็นตําแหน่งข้อมูล GraphQL โดยไม่ต้องเขียนโค้ดคอนโทรลเลอร์
  • ไคลเอ็นต์ที่ปลอดภัยประเภท: ไคลเอ็นต์ TypeScript ที่สร้างขึ้นให้การตรวจสอบความถูกต้องตามเวลาคอมไพล์สําหรับคิวรีและการกลายพันธุ์

วิธีการทำงาน

เมื่อคุณสร้างแอป Fabric โค้ดของคุณจะไหลผ่านขั้นตอนเหล่านี้:

# ลำดับขั้น เกิดอะไรขึ้น
1 นักพัฒนา คุณเขียนแอปในโปรแกรมแก้ไขที่คุณเลือก
2 TypeScript คุณเขียนคลาสเอนทิตีใน TypeScript
3 ตกแต่ง คุณใส่คําอธิบายประกอบคลาสและเขตข้อมูลด้วย @entity, @uuid, @text, @roleและตัวตกแต่งอื่นๆ
4 เค้าร่าง CLI คอมไพล์คลาสที่ตกแต่งเป็นสคีมาฐานข้อมูล นโยบายสิทธิ์ และการกําหนดค่า API
5 API สคีมาเผยแพร่เป็นจุดสิ้นสุด GraphQL
6 ลูกค้า ที่สร้างขึ้น 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) วิเคราะห์คลาสที่ตกแต่งของคุณและสร้าง:

  • Schema ฐานข้อมูล - ตาราง คอลัมน์ ข้อจํากัด และดัชนี
  • การกําหนดค่า 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 ตัวอย่าง
@entity() ทําเครื่องหมายคลาสเป็นเอนทิตีฐานข้อมูล @entity() class Product

ช่างตกแต่งอสังหาริมทรัพย์

ตกแต่ง ประเภทฐานข้อมูล ประเภทชนิดสคริปต์
@uuid() UNIQUEIDENTIFIER string
@text() NVARCHAR string
@int() INT number
@decimal() ทศนิยม number
@bool() BIT boolean
@date() DATETIME2 Date

ผู้ตกแต่งการอนุญาต

ตกแต่ง Purpose
@role() กําหนดสิทธิ์ตามบทบาท

ดู กําหนดสิทธิ์ของข้อมูล สําหรับรายละเอียดการให้สิทธิ์

ฟังก์ชัน

สร้างอินสแตนซ์หนึ่งUserDataFunctionsตัว และลงทะเบียนแต่ละฟังก์ชันโดยการเรียกใช้งานudf.func(name, handler, connections?)

ปฏิบัติตามกฎเหล่านี้เมื่อคุณกําหนดฟังก์ชัน:

  • วางพารามิเตอร์ไว้ RayfinContext ที่ใดก็ได้ในลายเซ็นตัวจัดการ รันไทม์จะระบุมันตามชนิด ฉีดมันเข้าไป และตัดออกจากอินพุตฟังก์ชันที่สร้างขึ้น
  • ประกาศการเชื่อมต่อสําหรับแต่ละโทเค็นที่ได้รับมอบหมายซึ่งฟังก์ชันต้องการ ละเว้น connection array สําหรับฟังก์ชันที่เข้าถึงเฉพาะข้อมูลแอปหรือไม่ต้องการโทเค็นที่มอบหมาย

ตัวอย่างต่อไปนี้ลงทะเบียนฟังก์ชันธรรมดาและฟังก์ชันที่ใช้บริบทการเรียกใช้งาน:

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 Web Token (JWT) ของผู้ใช้ที่ลงชื่อเข้าใช้ ถอดรหัสการอ้างสิทธิ์ sub เพื่อรับรหัสผู้ใช้ที่เสถียร
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
  3. ปรับใช้กับ Fabric - เรียกใช้ npx rayfin up เพื่อปรับใช้กับบริการ Fabric ที่มีการจัดการและใช้การเปลี่ยนแปลง Schema ของคุณ

การเปลี่ยนแปลงโมเดล TypeScript ของคุณจะเผยแพร่ไปทั่วทั้งสแต็กโดยอัตโนมัติ ตั้งแต่สคีมาฐานข้อมูลไปจนถึงตําแหน่งข้อมูล API ไปจนถึงประเภทไคลเอ็นต์

การอ นุ ญาต

สิทธิ์ถูกกําหนดควบคู่ไปกับโมเดลข้อมูลของคุณโดยใช้ @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;
}

วิธีการนี้ช่วยให้มั่นใจได้ว่า:

  • กฎความปลอดภัยอยู่ถัดจากข้อมูลที่พวกเขาปกป้อง
  • นิพจน์นโยบายที่ปลอดภัยชนิดจะตรวจจับข้อผิดพลาดในเวลาคอมไพล์
  • การปรับโครงสร้างฟิลด์เอนทิตีจะอัปเดตการตรวจสอบสิทธิ์โดยอัตโนมัติ