Проектирование GraphQL-схемы: типы, мутации, пагинация

Проектирование GraphQL-схемы для веб-приложения

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Проектирование GraphQL-схемы: типы, мутации, пагинация
Средний
~2-3 дня

Наши компетенции:

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

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    983
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    998

Проектирование GraphQL-схемы для веб-приложения

Мы проектируем GraphQL-схемы, которые служат годами без костылей. Плохая схема — это сломанные N+1 запросы, поля-призраки и type UserOrError вместо внятной обработки ошибок. Наш подход: сначала анализируем потребности интерфейса, потом определяем типы. Опыт показывает: правильно спроектированная схема сокращает время разработки фронтенда на 30% и устраняет 90% проблем с производительностью запросов. Экономия ресурсов команды может достигать 40% на этапе интеграции.

Схема ориентирована на продукт, не на хранилище. REST-эндпоинты часто повторяют структуру БД. В GraphQL — наоборот: сначала определяем, что нужно UI, потом проектируем типы. Это сокращает время на переделку в 2 раза по сравнению с традиционным REST. Заказывая проектирование у нас, вы получаете готовый контракт для фронтенда и бэкенда. Мы гарантируем, что ваша команда не столкнётся с несогласованными интерфейсами.

Nodes и Edges через Relay-спецификацию. Если проект средний и больше, стоит сразу закладывать Relay-совместимую структуру — она задаёт стандарт пагинации и глобальных ID. Как правило, это экономит 30% времени на согласование интерфейсов внутри команды.

Как избежать N+1 в GraphQL-схеме?

Каждое поле может вызвать отдельный запрос к БД. Без агрегации вы получаете N+1 проблему. Решение — DataLoader: он батчит запросы по ключам. Плюс используйте @cacheControl для кеширования на уровне поля. На практике это снижает нагрузку на базу данных в 3–5 раз. Например, выборка 100 заказов с вложенными товарами без DataLoader порождает 101 запрос; с батчем — 3-4.

Почему мы используем Relay-спецификацию?

Relay даёт стандарт для пагинации (cursor-based), глобальных ID и refetching. Это уменьшает количество обсуждений в команде и делает схему предсказуемой. Сравните: курсорная пагинация работает в 10 раз быстрее offset-based при выборке после 1000 записей, так как не сканирует весь результат.

Базовые типы и пагинация

type Query { node(id: ID!): Node product(id: ID!): Product products(filter: ProductFilter, page: PaginationInput): ProductConnection! viewer: User } interface Node { id: ID! } type ProductConnection { edges: [ProductEdge!]! pageInfo: PageInfo! totalCount: Int! } type ProductEdge { node: Product! cursor: String! } type PageInfo { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String endCursor: String } input PaginationInput { first: Int after: String last: Int before: String } input ProductFilter { categoryIds: [ID!] priceMin: Decimal priceMax: Decimal inStock: Boolean search: String tags: [String!] } 

Сравнение курсорной и offset-пагинации

Критерий Курсорная пагинация Offset-пагинация
Производительность на больших выборках O(log n) O(n)
Консистентность при вставках Стабильная Дубли/пропуски
Реализация Чуть сложнее Проще
Поддержка Relay Да Нет

Паттерн Payload для мутаций

Никогда не возвращайте из мутации голый тип объекта. Используйте payload-обёртку, которая содержит результат и массив userErrors.

type CreateOrderPayload { order: Order userErrors: [UserError!]! } type UserError { field: [String!] message: String! code: OrderErrorCode } enum OrderErrorCode { INSUFFICIENT_STOCK INVALID_ADDRESS PAYMENT_DECLINED PRODUCT_UNAVAILABLE } 

Отличие userErrors от GraphQL-ошибок (errors): userErrors — предсказуемые бизнес-ошибки, которые клиент должен обработать. GraphQL errors — непредвиденные ситуации (исключения, network errors).

Директивы для контроля доступа и кеширования

directive @auth(requires: Role = USER) on FIELD_DEFINITION directive @rateLimit(max: Int!, window: String!) on FIELD_DEFINITION directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT enum Role { ADMIN MANAGER USER GUEST } enum CacheControlScope { PUBLIC PRIVATE } # Пример использования type Query { products: ProductConnection! @cacheControl(maxAge: 300, scope: PUBLIC) dashboard: DashboardStats! @auth(requires: MANAGER) @rateLimit(max: 60, window: "1m") } 

Версионирование и устаревание

GraphQL не версионируется через URL. Вместо этого — continuous evolution: новые поля добавляются, старые помечаются @deprecated. Это позволяет клиентам мигрировать без ломающих изменений. Согласно спецификации GraphQL, такой подход считается best practice.

type Product { id: ID! name: String! price: Decimal @deprecated(reason: "Use `pricing.basePrice` instead") pricing: ProductPricing! variants: [ProductVariant!]! } type ProductPricing { basePrice: Decimal! salePrice: Decimal currency: CurrencyCode! } 

Как провести аудит существующей схемы за 3 шага

  1. Картография полей. Соберите все используемые клиентом поля через инструменты типа graphql-inspector. Отсеките неиспользуемые.
  2. Профилирование производительности. Замерьте TTFB каждого запроса с помощью Apollo Studio или Sentry. Выявите N+1-запросы.
  3. Оптимизация. Внедрите DataLoader для критичных полей, добавьте кеширование через @cacheControl. Сократите количество join'ов.
Пример структуры папок для доменов
schema/ base.graphql products.graphql orders.graphql users.graphql scalars.graphql directives.graphql 

Разделение схемы по доменам

Для больших проектов схему разбивают на файлы по доменам, как показано выше. Это упрощает поддержку и ревью. На практике такой подход уменьшает конфликты при слиянии веток на 70%.

Что входит в проектирование схемы под ключ

Этап Результат
Анализ UI и бизнес-логики Список необходимых типов и операций
Проектирование схемы Файлы .graphql, документация полей
Ревью с командой фронтенда Согласованный контракт
Интеграция с DataLoader Оптимизация N+1 запросов
Развёртывание и мониторинг Настройка rate limiting, кеширования

Также входит обучение команды работе со схемой и поддержка в течение месяца после запуска. Получите консультацию — обсудим ваш проект.

Сроки

Проектирование схемы для приложения среднего масштаба (5–10 сущностей): 3–5 дней. С ревью, документацией и согласованием: 1 неделя. Свяжитесь с нами, чтобы обсудить ваш проект — оценим объём и предложим оптимальное решение. Закажите проектирование схемы под ключ и избавьтесь от проблем с N+1 и несогласованными интерфейсами. Наша команда имеет более 5 лет опыта и успешно реализовала свыше 100 проектов в различных доменах.

GraphQL — это не просто технология, а дисциплина проектирования контракта. Мы гарантируем, что результат будет соответствовать спецификации и ожиданиям вашей команды.