Fabric 앱에 대한 데이터 모델 정의

Fabric 앱은 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;
}

이 엔터티는 id, title, description, createdAtupdatedAt 열이 있는 Todo 테이블을 생성합니다.

기본 키

모든 엔터티는 기본 키로 명명된 string UUID id 필드를 사용합니다. id 명시적으로 선언하지 않으면 Fabric 앱은 스키마에 자동으로 추가합니다.

  • id 필드는 만들기 작업 중에 선택 사항입니다. 생략하면 서버에서 UUID를 생성합니다.
  • 클라이언트 생성 식별자를 선호하는 경우 생성 시 사용자 고유의 UUID를 제공할 수 있습니다.
  • 복합 기본 키 및 사용자 지정 키 이름은 지원되지 않습니다.
@entity()
export class Note {
  @uuid() id!: string;  // UUID primary key, auto-generated when omitted
  @text() title!: string;
  @text() content!: string;
}

지원되는 데이터 형식

다음 데코레이터를 사용하여 필드 형식을 정의합니다.

데코레이터 Type Description
@uuid() string 고유 식별자 필드입니다.
@text() string 선택적 길이 제약 조건이 있는 텍스트 필드입니다.
@int() number 정수 필드입니다.
@decimal() number 10진수 또는 숫자 필드입니다.
@boolean() 불리언 True 또는 false 필드입니다.
@date() Date 날짜 및 시간 필드, ISO 문자열 또는 Date 개체에서 직렬화합니다.
@email() string 전자 메일 유효성 검사가 있는 텍스트 필드입니다.
@set() string 열거된 문자열 리터럴 집합입니다.

여러 형식의 예제

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

형식 한정자

필드 데코레이터에 한정자를 추가하여 유효성 검사 및 제약 조건을 구성합니다.

한정자 Description
{ optional: true } NULL 값을 허용합니다. 필드는 기본적으로 필수입니다.
{ unique: true } 고유한 제약 조건을 추가합니다.
{ default: value } 기본값 식을 설정합니다.
{ max: n }, { min: n } 문자열 길이 제약 조건(최대 및 최소 문자 수).
{ min: n }, { max: n } 숫자 값 제약 조건입니다.

비고

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 앱은 관계를 정의할 때 외래 키 열을 자동으로 생성합니다.

  • 일대다 – 부모에는 @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 앱은 자동으로 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 앱은 기본 제공 @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;
};

새 엔터티를 만들 때마다 이 형식을 업데이트합니다.

스키마 변경 사항을 적용합니다.

엔터티를 정의하거나 수정한 후 데이터베이스에 변경 내용을 적용합니다.

  1. 업데이트된 스키마를 Fabric에 배포하세요:

    npx rayfin up db apply
    
  2. 스키마 변경에 파괴적인 작업(열 삭제, 테이블 이름 바꾸기)이 포함된 경우 CLI는 경고하고 진행을 거부합니다. 안전 검사를 무시하려면 --force을(를) 사용하세요:

    npx rayfin up db apply --force
    

비고

사용하면 --force 데이터가 손실될 수 있습니다. 계속하기 전에 나열된 작업을 신중하게 검토합니다.

모범 사례

  • 외래 키 필드를 코드에서 읽거나 설정해야 하는 경우에만 정의합니다. Fabric 앱은 탐색 데코레이터에서 자동으로 생성합니다.
  • 내보낸 ESM JavaScript가 올바르게 해석되도록 엔터티 파일에서 .js 확장자를 사용하는 상대 가져오기를 사용하세요.
  • 권한 부여 패턴 및 역할 기반 액세스는 데이터 권한 정의를 참조하세요.

Troubleshooting

누락된 관계

관계가 API에 표시되지 않는 경우 다음을 확인합니다.

  • 탐색 데코레이터(@one() 또는 @many())가 있습니다.
  • 엔터티가 rayfin/data/schema.ts에 등록됩니다.