Gambaran umum model pemrograman

Rayfin SDK menggunakan model pemrograman berbasis dekorator di mana Anda cukup satu kali menentukan skema data di TypeScript dan secara otomatis mendapatkan API siap produksi, klien yang aman secara tipe, serta infrastruktur.

Konsep Utama

Rayfin SDK menggabungkan tiga elemen inti:

  • Skema berbasis dekorator: Gunakan dekorator TypeScript untuk menentukan model data, izin, dan hubungan.
  • Pembuatan API otomatis: Kelas yang didekorasi menjadi titik akhir GraphQL tanpa menulis kode pengontrol.
  • Klien yang aman terhadap tipe: Klien TypeScript yang dihasilkan menyediakan validasi pada waktu kompilasi untuk kueri dan mutasi.

Cara kerjanya

Saat Anda membuat aplikasi Fabric, kode Anda mengalir melalui tahap ini:

# Stage Apa yang terjadi
1 Pengembang Anda menulis aplikasi di editor pilihan Anda.
2 TypeScript Anda menulis kelas entitas di TypeScript.
3 Decorators Anda membuat anotasi kelas dan kolom dengan @entity, @uuid, @text, @role, dan dekorator lainnya.
4 Schema CLI mengkompilasi kelas yang didekorasi ke dalam skema database, kebijakan izin, dan konfigurasi API.
5 Antarmuka Pemrograman Aplikasi (API) Skema diterbitkan sebagai titik akhir GraphQL.
6 Client RayfinClient yang dihasilkan menyediakan klien data dan autentikasi yang aman secara tipe melalui endpoint tersebut.
7 Application Aplikasi frontend Anda menggunakan klien untuk membaca dan menulis data.

1. Definisikan model data dengan dekorator

Anda menentukan struktur data anda menggunakan kelas TypeScript dan dekorator dari @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. Pembuatan skema

Rayfin CLI (npx rayfin) menganalisis kelas yang Anda dekorasi dan menghasilkan:

  • Skema database - Tabel, kolom, batasan, dan indeks
  • Konfigurasi API - Definisi titik akhir GraphQL
  • Kebijakan izin - Keamanan tingkat baris dan kontrol akses tingkat bidang

4. Penggunaan klien yang aman terhadap tipe

API GraphQL tersedia untuk melakukan operasi CRUD pada database Anda. Rayfin SDK menyediakan operasi klien data di luar kotak untuk membaca atau menulis atau menghapus data.

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

Referensi dekorator

Rayfin SDK menyediakan dekorator untuk pola pemodelan data umum:

Dekorator Entitas

Dekorator Kegunaan Example
@entity() Menandai kelas sebagai entitas database @entity() class Product

Dekorator properti

Dekorator Jenis database Jenis TypeScript
@uuid() UNIQUEIDENTIFIER string
@text() NVARCHAR string
@int() INT number
@decimal() DECIMAL number
@bool() BIT boolean
@date() DATETIME2 Date

Dekorator izin

Dekorator Kegunaan
@role() Menentukan izin berbasis peran

Lihat Menentukan izin data untuk detail otorisasi.

Functions

Buat satu UserDataFunctions instance, dan daftarkan setiap fungsi dengan memanggil udf.func(name, handler, connections?).

Ikuti aturan berikut saat Anda mendefinisikan sebuah fungsi:

  • Tempatkan parameter RayfinContext di mana saja dalam signature handler. Runtime mengidentifikasinya berdasarkan tipe, menyuntikkannya, dan mengecualikannya dari input fungsi yang dihasilkan.
  • Deklarasikan koneksi untuk setiap token yang didelegasikan yang dibutuhkan fungsi tersebut. Hilangkan array koneksi untuk fungsi yang hanya mengakses data aplikasi atau tidak memerlukan token delegasi.

Contoh berikut mendaftarkan fungsi biasa dan fungsi yang menggunakan konteks pemanggilan:

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 menyediakan layanan runtime fungsi:

Anggota Kegunaan
ctx.accessToken Menyediakan Rayfin JSON Web Token (JWT) milik pengguna yang masuk. Pecahkan sub klaim untuk mendapatkan ID pengguna yang stabil.
ctx.Tokens.<Audience> Mendapatkan token sumber daya yang disediakan platform untuk audiens yang dideklarasikan dalam anotasi RayfinContext. Fungsi yang Terdeploy menggunakan identitas aplikasi dan izinnya. Untuk detail, lihat Hubungkan Fungsi ke sumber daya eksternal.
ctx.getSecret('NAME') Mendapatkan rahasia untuk invokasi saat ini. Mengembalikan undefined jika rahasia tidak ditetapkan.
ctx.getDataClient() Mendapatkan API data yang diketik untuk entitas Anda. Klien mendukung operasi buat, findMany, perbarui, hapus, dan upsert.
ctx.baseUrl Menyediakan endpoint Rayfin untuk item saat ini.
ctx.publishableKey Menyediakan kunci yang dapat dipublikasikan untuk item saat ini.

Untuk petunjuk tentang penyiapan, debugging secara lokal, dan penyebaran, lihat Menggunakan Fungsi di Fabric Apps.

Alur kerja pengembangan

Siklus pengembangan yang khas mengikuti pola ini:

  1. Menentukan atau memodifikasi model data - Menambahkan atau memperbarui kelas TypeScript dengan dekorator
  2. Test secara lokal dengan backend jarak jauh - Jalankan npm run dev untuk menguji perubahan kode frontend Anda terhadap backend Aplikasi Anda di Fabric.
  3. Deploy ke Fabric - Jalankan npx rayfin up untuk melakukan deployment ke layanan Fabric yang dikelola dan menerapkan perubahan skema Anda.

Perubahan pada model TypeScript Anda secara otomatis disebarluaskan melalui seluruh tumpukan — dari skema database ke titik akhir API ke jenis klien.

Authorization

Izin didefinisikan bersama model data Anda menggunakan dekorator @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;
}

Pendekatan ini memastikan:

  • Aturan keamanan berada di samping data yang mereka lindungi
  • Ekspresi kebijakan yang aman terhadap tipe mendeteksi kesalahan saat kompilasi
  • Pemfaktoran ulang kolom entitas secara otomatis memperbarui pemeriksaan hak akses