PassFront
  1. PassFront
  2. База знаний
  3. Основы React

Как в одном приложении связать React, GraphQL и гексагональный сервер?

Основы React

Связка «React + GraphQL + гексагональный сервер» складывается в три слоя, где GraphQL — входной порт сервера, а для клиента — источник данных.

Архитектура целиком

React (UI-адаптер клиента)
  → GraphQL-клиент (Apollo / urql / graphql-request + TanStack Query)
    → GraphQL API (входной адаптер сервера)
      → резолверы → use cases (ядро домена)
        → выходные порты → адаптеры (БД, внешние API)

Сервер: GraphQL как driving-адаптер

  • Ядро — чистые домен и use cases, ничего не знают о GraphQL.
  • GraphQL-слой — адаптер: схема описывает контракт, резолверы тонкие — маппят запрос в вызов use case и результат в тип схемы:
const resolvers = {
  Mutation: {
    placeOrder: (_, { input }, ctx) =>
      ctx.useCases.placeOrder.execute(toCommand(input)), // только маппинг
  },
};
  • Бизнес-правила в резолверах — антипаттерн: логика утечёт из ядра.
  • Инфраструктура (Postgres, платёжка) — за выходными портами; DI собирает всё в context.

Клиент: React + GraphQL-слой

  • Схема — общий контракт: из неё генерируются TypeScript-типы и хуки (GraphQL Code Generator) — типобезопасность от БД до компонента.
  • Данные — через клиент с кешем (Apollo/urql) или graphql-request + TanStack Query; компоненты вызывают хуки (useOrderQuery), не зная про транспорт.
  • При желании гексагональности и на клиенте: GraphQL-вызовы прячутся за клиентскими портами (OrderGateway), а React использует use cases.

Мысли для ответа

Schema-first контракт между командами; тонкие резолверы; независимость ядра от GraphQL (завтра рядом можно поставить REST-адаптер на те же use cases); кодогенерация типов на клиент.

Коротко для собеседования

GraphQL — входной адаптер гексагонального сервера: тонкие резолверы вызывают use cases ядра, инфраструктура за выходными портами. React потребляет API через GraphQL-клиент с кешем и сгенерированными из схемы типами/хуками. Схема — контракт; ядро не знает о GraphQL, поэтому транспорт заменяем.

Другие вопросы раздела