Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Fabric Apps предоставляет типобезопасный клиент GraphQL, который позволяет выполнять операции создания, чтения, обновления и удаления без написания запросов вручную. Клиент автоматически создает GraphQL из вызовов методов и возвращает типизированные сущности на основе определений модели данных.
Необходимые условия
- Проект Fabric Apps с определенными моделями данных. См. раздел "Определение моделей данных".
- Серверные службы, работающие локально или развернутые в Fabric.
Инициализация клиента
Создайте экземпляр RayfinClient с URL-адресом вашего бэкенда, публикуемым ключом и типом схемы:
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>. API fluent предоставляет методы для запроса, фильтрации, сортировки и разбиения на страницы.
Получить все записи
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');
Возвращает полную сущность или null если запись с этим идентификатором отсутствует.
Фильтрация записей
where() Используйте метод для фильтрации результатов:
const pinnedNotes = await client.data.Note.select([
'id',
'title',
'isPinned',
])
.where({ isPinned: { eq: true } })
.execute();
Операторы фильтрации
| Operator | Description | Example |
|---|---|---|
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();
}
Замечание
Свойство 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(),
});
Обе формы создают один и тот же результат. Используйте первую форму, если вы уже знаете идентификатор связанной сущности и хотите избежать дополнительного запроса.
Обновить записи
update() Используйте метод для изменения существующих записей. Передайте объект фильтра и объект, содержащий поля для обновления:
await client.data.Note.update(
{ id: 'note-123' },
{
title: 'Updated title',
updatedAt: new Date(),
}
);
Обновление связей
Чтобы изменить связь, передайте новую связанную сущность или просто её идентификатор:
// 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вместо этого. - Связи "многие ко многим" не поддерживаются. Используйте явно заданную сущность связи с двумя
@one()декораторами навигации. - Свойство
totalCountуPagedResultне заполняется на стороне сервера.