Fabric Apps には、生のクエリを記述せずに作成、読み取り、更新、および削除の操作を実行できる、タイプ セーフな GraphQL クライアントが用意されています。 クライアントは、メソッド呼び出しから GraphQL を自動的に生成し、データ モデル定義に基づいて型指定されたエンティティを返します。
前提条件
- データ モデルが定義された Fabric Apps プロジェクト。 データ モデルの定義を参照してください。
- ローカルで実行されているか、Fabricにデプロイされているバックエンド サービス。
クライアントを初期化する
バックエンド URL、発行可能なキー、スキーマの種類を使用して RayfinClient をインスタンス化します。
import { RayfinClient } from '@microsoft/rayfin-client';
import type { Note } from '../rayfin/data/Note';
import type { Notebook } from '../rayfin/data/Notebook';
type AppSchema = {
Note: Note;
Notebook: Notebook;
};
const client = new RayfinClient<AppSchema>({
baseUrl: import.meta.env.VITE_RAYFIN_API_URL ?? 'http://localhost:5168',
publishableKey: 'pk-your-project-key',
});
ジェネリック型引数を使用すると、TypeScript はすべてのデータ操作にオートコンプリートと型チェックを提供できます。
データの読み取り
client.data.<EntityName>を介してエンティティ コレクションにアクセスします。 fluent API には、クエリ、フィルター処理、並べ替え、改ページ処理のメソッドが用意されています。
すべてのレコードを取得
const notes = await client.data.Note.select([
'id',
'title',
'content',
'createdAt',
'isPinned',
]).execute();
主キーを使用して単一のレコードを取得する
const note = await client.data.Note.findByPk('00000000-0000-0000-0000-000000000000');
これにより、完全なエンティティが返されるか、その ID を持つレコードが存在しない場合は null が返されます。
レコードのフィルター処理
where()メソッドを使用して結果をフィルター処理します。
const pinnedNotes = await client.data.Note.select([
'id',
'title',
'isPinned',
])
.where({ isPinned: { eq: true } })
.execute();
フィルター演算子
| Operator | 説明 | 例 |
|---|---|---|
eq |
等しい | { status: { eq: 'active' } } |
ne |
等しくない | { status: { ne: 'archived' } } |
gt |
より大きい | { age: { gt: 18 } } |
gte |
以上 | { age: { gte: 21 } } |
lt |
未満 | { price: { lt: 100 } } |
lte |
より小さいか等しい | { price: { lte: 50 } } |
contains |
部分文字列を含む | { title: { contains: 'draft' } } |
結果を並べ替える
orderBy()を使用してクエリ結果を並べ替えます。
const notes = await client.data.Note.select([
'id',
'title',
'createdAt',
])
.orderBy({ createdAt: 'desc' })
.execute();
複数列で並べ替え:
const notes = await client.data.Note.select([
'id',
'title',
'isPinned',
'createdAt',
])
.orderBy({ isPinned: 'desc' })
.orderBy({ createdAt: 'desc' })
.execute();
関係間を移動
@one()および@many()デコレーターとのリレーションシップを定義する場合は、同じクエリに関連エンティティ フィールドを含めることができます。
const notes = await client.data.Note.select([
'id',
'title',
'content',
'notebook.id',
'notebook.name',
'notebook.color',
])
.execute();
各ノートには、個別のクエリを必要とせずに、関連付けられているノートブック データが含まれています。
大きな結果セットの改ページ
大規模なリストにはカーソルベースのページネーションを使用します:
const page = await client.data.Note.select([
'id',
'title',
'createdAt',
])
.orderBy({ createdAt: 'desc' })
.first(25)
.executePaginated();
console.log('Items:', page.items);
console.log('Has next page:', page.hasNextPage);
console.log('End cursor:', page.endCursor);
カーソルを使用して次のページを取得します:
if (page.hasNextPage) {
const nextPage = await client.data.Note.select([
'id',
'title',
'createdAt',
])
.orderBy({ createdAt: 'desc' })
.first(25)
.after(page.endCursor)
.executePaginated();
}
Note
totalCountプロパティはPagedResult型に表示されますが、バックエンドによって設定されません。
items.lengthを使用して、現在のページの結果をカウントします。
レコードを作成する
create() メソッドを使用して、新しいレコードを挿入します。
const newNote = await client.data.Note.create({
title: 'Meeting notes',
content: 'Discussion points from the team sync',
isPinned: false,
isArchived: false,
createdAt: new Date(),
updatedAt: new Date(),
user_id: 'user-123',
});
このメソッドは、自動生成された idを含め、すべてのフィールドが設定された作成済みエンティティを返します。
リレーションシップを持つレコードを作成する
リレーションシップを持つエンティティを作成する場合は、関連する完全なオブジェクトまたは主キーのみを持つオブジェクトを渡します。
// Option 1: Pass just the ID
const note = await client.data.Note.create({
title: 'Weekly summary',
content: 'Summary of this week',
notebook: { id: 'notebook-456' },
isPinned: false,
isArchived: false,
createdAt: new Date(),
updatedAt: new Date(),
});
// Option 2: Pass the full object
const notebook = await client.data.Notebook.findByPk('notebook-456');
const note = await client.data.Note.create({
title: 'Weekly summary',
content: 'Summary of this week',
notebook: notebook,
isPinned: false,
isArchived: false,
createdAt: new Date(),
updatedAt: new Date(),
});
どちらの形式でも同じ結果が生成されます。 関連エンティティの ID が既にわかっており、余分なフェッチを回避したい場合は、最初のフォームを使用します。
レコードの更新
既存のレコードを変更するには、 update() メソッドを使用します。 フィルターオブジェクトと、更新するフィールドを含むオブジェクトを渡します。
await client.data.Note.update(
{ id: 'note-123' },
{
title: 'Updated title',
updatedAt: new Date(),
}
);
関係性の更新
リレーションシップを変更するには、新しい関連エンティティまたはその ID のみを渡します。
// Move a note to a different notebook
await client.data.Note.update(
{ id: 'note-123' },
{ notebook: { id: 'new-notebook-789' } }
);
レコードを削除する
フィルターに一致するレコードを削除するには、 delete() メソッドを使用します。
await client.data.Note.delete({ id: 'note-123' });
このメソッドは、バックエンドが削除を確認したときに解決されます。 フィルターに一致するレコードがない場合でも、メソッドは成功します。
認証の処理
認証が有効になっている場合は、データ操作を実行する前にサインインします。
await client.auth.signIn({ email, password });
// All subsequent data calls include authentication context
const notes = await client.data.Note.select(['id', 'title']).execute();
クライアントは、認証セッションをすべてのデータ API 呼び出しに自動的にアタッチします。 トークンを手動で渡す必要はありません。
ベスト プラクティス
- 必要なフィールドのみを選択 します。ペイロード のサイズを小さくし、パフォーマンスを向上させるために使用するフィールドのみをフェッチします。
-
大規模なリストではページネーションを使用する –
first()とexecutePaginated()を使用して、一度に何千件ものレコードを取得しないようにします。 - バッチ リレーションシップ クエリ – 個別の要求を行うのではなく、同じクエリに関連エンティティ フィールドを含めます。
- 頻繁にアクセスされるデータをキャッシュ する – API 呼び出しを減らすために、静的参照データをメモリに格納します。
現在の制限
-
count()メソッドは fluent クライアントでは使用できません。 最小フィールドを選択し、代わりにresults.lengthを使用します。 - 多対多リレーションシップはサポートされていません。 2 つの
@one()ナビゲーション デコレーターで明示的な結合エンティティを使用します。 -
totalCountのPagedResultプロパティは、バックエンドによって設定されません。