12k
All articles

Создание приложений на основе данных с React Admin

Архитектура React Admin: методы dataProvider, CRUD-виды, аутентификация и повторно используемые экраны списка и редактирования для backend-agnostic приложений.

OpenReplay Team
OpenReplay Team
Создание приложений на основе данных с React Admin

Если вы когда-либо создавали административную панель с нуля — настраивая таблицы, формы, пагинацию и API-вызовы вручную — вы знаете, сколько шаблонного кода требуется написать до того, как вы напишете хотя бы одну строку бизнес-логики. React Admin решает эту проблему, предоставляя структурированный фреймворк для создания CRUD-приложений поверх любого API. В этой статье рассматривается, как он работает, с акцентом на архитектуру, которая делает его независимым от бэкенда и действительно переиспользуемым.

Ключевые выводы

  • React Admin — это React-фреймворк для создания административных панелей на основе данных, а не UI-шаблон. Он разделяет слой данных и слой UI через абстракцию dataProvider.
  • dataProvider построен на основе девяти базовых методов, которые адаптируют React Admin к любому бэкенду — REST, GraphQL, Supabase или другим — делая фреймворк действительно независимым от бэкенда.
  • Представления списков и редактирования являются декларативными: вы компонуете компоненты полей и компоненты ввода, а React Admin автоматически обрабатывает получение данных, пагинацию, сортировку и разрешение связей.
  • Аутентификация, управление доступом на основе ролей и обновления в реальном времени обрабатываются через отдельные провайдеры и опциональные расширения, сохраняя ядро фреймворка сфокусированным и модульным.

Что на самом деле представляет собой React Admin

React Admin — это не UI-шаблон. Это React-фреймворк, специально созданный для административных панелей на основе данных и внутренних инструментов. Он поставляется с компонентами для отображения списков, создания, редактирования и удаления записей, но реальная ценность заключается в том, как он разделяет слой данных и слой UI.

В своей основе React Admin v5 построен на React Query, react-hook-form и react-router. По умолчанию используется MUI, но фреймворк не ограничивается им — React Admin поддерживает headless-режим, что означает возможность использовать собственную библиотеку компонентов при необходимости.

Три строительных блока: Admin, Resource и dataProvider

Каждое приложение React Admin начинается с трёх концепций:

  • <Admin> — корневой компонент, который связывает всё воедино
  • <Resource> — сопоставляет имя с набором CRUD-представлений и API-эндпоинтом
  • dataProvider — адаптер между React Admin и вашим бэкендом
import { Admin, Resource } from "react-admin"
import { dataProvider } from "./dataProvider"
import { MovieList } from "./MovieList"
import { MovieEdit } from "./MovieEdit"

const App = () => (
  <Admin dataProvider={dataProvider}>
    <Resource name="movies" list={MovieList} edit={MovieEdit} />
  </Admin>
)

Когда пользователь переходит к списку фильмов, React Admin вызывает dataProvider.getList("movies", params). Когда он редактирует запись, вызывается dataProvider.update("movies", params). UI никогда не обращается к вашему API напрямую.

Как работает dataProvider в React Admin

dataProvider построен на основе девяти базовых методов: getList, getOne, getMany, getManyReference, create, update, updateMany, delete и deleteMany. Каждый метод получает объект запроса и возвращает Promise, а провайдеры могут быть расширены дополнительными методами при необходимости.

const dataProvider = {
  getList: async (resource, params) => {
    const { page, perPage } = params.pagination
    const { field, order } = params.sort
    const url = `${apiUrl}/${resource}?page=${page}&perPage=${perPage}&sort=${field}&order=${order}`
    const { json, headers } = await httpClient(url, { signal: params.signal })
    return {
      data: json,
      total: parseInt(headers.get("content-range").split("/").pop(), 10),
    }
  },
  // ...другие методы
}

React Admin не важно, является ли ваш бэкенд REST, GraphQL, Supabase или даже IndexedDB. Пока каждая запись имеет согласованное поле id, а ваш dataProvider возвращает ожидаемую структуру, всё работает. Существуют готовые адаптеры для распространённых бэкендов — ra-data-simple-rest, ra-data-graphql и другие — поэтому часто не требуется писать адаптер с нуля.

Обработка аутентификации

Аутентификация не встроена в dataProvider. React Admin использует отдельный authProvider для входа, выхода и проверки прав доступа. Распространённый паттерн — сохранять токен после входа и читать его внутри вашего dataProvider при выполнении запросов, но React Admin также поддерживает интеграцию с внешними провайдерами идентификации.

const httpClient = (url, options = {}) => {
  options.user = {
    authenticated: true,
    token: localStorage.getItem("token"),
  }
  return fetchUtils.fetchJson(url, options)
}

Создание представлений списков и редактирования

После настройки dataProvider создание представлений становится в основном декларативным. Для представлений списков компонент React Admin <Datagrid> отображает столбцы на основе компонентов полей, которые вы компонуете. Обратите внимание, что <Datagrid> по-прежнему широко используется, но в новых версиях также представлен <DataTable> как более современная альтернатива.

import { List, Datagrid, TextField, DateField, ReferenceField } from "react-admin"

export const MovieList = () => (
  <List>
    <Datagrid rowClick="edit">
      <TextField source="title" />
      <DateField source="release" />
      <ReferenceField source="director_id" reference="directors">
        <TextField source="lastname" />
      </ReferenceField>
    </Datagrid>
  </List>
)

<ReferenceField> автоматически вызывает dataProvider.getMany("directors", ...) для разрешения связанных записей — ручная загрузка не требуется.

Формы редактирования следуют тому же паттерну с использованием <Edit> и <SimpleForm>:

import { Edit, SimpleForm, TextInput, DateInput } from "react-admin"

export const MovieEdit = () => (
  <Edit>
    <SimpleForm>
      <TextInput source="title" />
      <DateInput source="release" />
    </SimpleForm>
  </Edit>
)

Когда требуется пользовательская логика

Для поведения, специфичного для ресурса — например, удаления связанных записей перед удалением родительской — React Admin предоставляет withLifecycleCallbacks:

import { withLifecycleCallbacks } from "react-admin"

export const dataProvider = withLifecycleCallbacks(baseDataProvider, [
  {
    resource: "movies",
    beforeDelete: async (params, dp) => {
      const { data: reviews } = await dp.getList("reviews", {
        filter: { movie_id: params.id },
        pagination: { page: 1, perPage: 1000 },
        sort: { field: "id", order: "DESC" },
      })
      await dp.deleteMany("reviews", { ids: reviews.map((r) => r.id) })
      return params
    },
  },
])

Это позволяет держать вашу бизнес-логику близко к слою данных, не распыляя её по компонентам.

Что React Admin не делает из коробки

Несколько моментов, которые стоит знать, прежде чем вы примете решение:

  • RBAC (детализированное управление доступом на основе ролей) требует корпоративного модуля; базовые проверки прав доступа обрабатываются через authProvider
  • Обновления в реальном времени требуют совместимого realtime data provider и дополнительной настройки
  • Загрузка файлов требует пользовательской логики dataProvider для обработки multipart/form-data

React Admin также совместим с фреймворками, такими как Next.js (включая Pages Router и App Router), и поддерживает альтернативные решения для маршрутизации помимо настроек по умолчанию.

Заключение

Сила React Admin заключается в его абстракции dataProvider. После того как вы реализуете эти базовые методы для вашего API, вы получаете полнофункциональную CRUD-панель администрирования с сортировкой, фильтрацией, пагинацией и обработкой связей — без необходимости создавать всё это самостоятельно. Начните с готового адаптера, если он подходит для вашего бэкенда, напишите пользовательский, если нет, и добавляйте аутентификацию и lifecycle callbacks по мере роста вашего приложения.

Часто задаваемые вопросы

Могу ли я использовать React Admin с GraphQL-бэкендом?

Да. React Admin по своей природе независим от бэкенда. Вы можете использовать официальный адаптер ra-data-graphql или написать пользовательский dataProvider, который сопоставляет необходимые методы с вашими GraphQL-запросами и мутациями. Пока каждая запись включает согласованное поле id, а ваш провайдер возвращает ожидаемую структуру ответа, React Admin работает одинаково независимо от бэкенда.

Как React Admin обрабатывает связи между ресурсами?

React Admin предоставляет компоненты ссылок, такие как ReferenceField и ReferenceInput, которые автоматически загружают связанные записи через ваш dataProvider. Например, ReferenceField вызывает dataProvider.getMany для разрешения внешних ключей в отображаемые значения. Вы объявляете связь в дереве компонентов, а React Admin обрабатывает загрузку данных и кэширование за кулисами.

Подходит ли React Admin для production-приложений со сложными правами доступа?

Open-source версия поддерживает базовую аутентификацию и простые проверки прав доступа через authProvider. Для детализированного управления доступом на основе ролей, такого как скрытие полей или ограничение действий по ролям, требуется корпоративный RBAC-модуль. Оцените ваши требования к правам доступа заранее, чтобы решить, соответствует ли бесплатная версия вашим потребностям.

Могу ли я настроить внешний вид помимо стандартной темы Material UI?

Да. React Admin по умолчанию использует MUI, но поддерживает headless-режим, что означает возможность замены всего UI-слоя на вашу собственную библиотеку компонентов. Вы также можете настроить тему MUI, переопределить отдельные компоненты или создать полностью пользовательские представления, продолжая использовать хуки React Admin для загрузки данных, обработки форм и маршрутизации.

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.