PurpleSchool — курсы программирования онлайн
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развития
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    GraphQL с нуля: схемы, резолверы и интеграция с React

    GraphQL с нуля: схемы, резолверы и интеграция с React

    Аватар автора GraphQL с нуля: схемы, резолверы и интеграция с React

    Антон Ларичев

    Иконка календаря14 июня 2026
    GraphQLReactApollo ClientBackendAPImiddleИконка уровня middle
    Картинка поста GraphQL с нуля: схемы, резолверы и интеграция с React

    Введение

    GraphQL — это язык запросов к API и среда выполнения для них, разработанная Facebook в 2012 году и открытая в 2015. В отличие от REST, где клиент получает фиксированный набор данных по URL, GraphQL позволяет клиенту запросить именно те поля, которые ему нужны. Это решает две классические проблемы REST: over-fetching (получение лишних данных) и under-fetching (необходимость нескольких запросов для одной сущности).

    В этой статье разберём три кита GraphQL: схемы (Schema), резолверы (Resolvers) и интеграцию с React через Apollo Client. После прочтения вы сможете поднять свой первый сервер и подключить его к фронтенду.

    Установка сервера

    Начнём с минимального сервера на Apollo Server. Установим зависимости:

    npm install @apollo/server graphql
    

    Создадим файл server.js:

    import { ApolloServer } from '@apollo/server';
    import { startStandaloneServer } from '@apollo/server/standalone';
    
    // Описание схемы на языке SDL
    const typeDefs = `#graphql
      type Book {
        id: ID!
        title: String!
        author: String!
      }
    
      type Query {
        books: [Book!]!
        book(id: ID!): Book
      }
    `;
    
    // Тестовые данные
    const books = [
      { id: '1', title: 'Чистый код', author: 'Роберт Мартин' },
      { id: '2', title: 'Совершенный код', author: 'Стив Макконнелл' },
    ];
    
    // Резолверы — функции, возвращающие данные для каждого поля
    const resolvers = {
      Query: {
        books: () => books,
        book: (_, { id }) => books.find((b) => b.id === id),
      },
    };
    
    const server = new ApolloServer({ typeDefs, resolvers });
    const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });
    console.log(`Сервер готов: ${url}`);
    

    Схемы и типы

    Схема — это контракт между клиентом и сервером. Она описывает, какие данные доступны и какие операции можно выполнять. GraphQL поддерживает скалярные типы (Int, Float, String, Boolean, ID) и пользовательские объекты.

    Восклицательный знак (!) означает, что поле не может быть null. Квадратные скобки ([Book!]!) описывают массив, элементы которого тоже не могут быть null.

    Помимо Query существует Mutation для изменения данных и Subscription для подписки на события:

    type Mutation {
      addBook(title: String!, author: String!): Book!
      deleteBook(id: ID!): Boolean!
    }
    
    type Subscription {
      bookAdded: Book!
    }
    

    Резолверы

    Резолвер — это функция, которая возвращает значение для конкретного поля схемы. Сигнатура у всех резолверов одинаковая:

    resolver(parent, args, context, info)
    

    Где:

    • parent — результат родительского резолвера;
    • args — аргументы, переданные в поле;
    • context — общий объект для запроса (часто содержит юзера и подключение к БД);
    • info — мета-информация о запросе.

    Добавим мутацию:

    const resolvers = {
      Query: {
        books: () => books,
      },
      Mutation: {
        addBook: (_, { title, author }) => {
          const newBook = { id: String(books.length + 1), title, author };
          books.push(newBook);
          return newBook;
        },
      },
    };
    

    Если у объекта есть поле, требующее вычисления, добавьте резолвер на уровне типа:

    Book: {
      // Вычисляемое поле — короткое описание
      shortTitle: (parent) => parent.title.slice(0, 20),
    },
    

    Интеграция с React

    На фронте используем Apollo Client. Устанавливаем пакеты:

    npm install @apollo/client graphql
    

    Инициализируем клиент и оборачиваем приложение в провайдер:

    import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
    
    const client = new ApolloClient({
      uri: 'http://localhost:4000/',
      cache: new InMemoryCache(), // нормализованный кэш по __typename и id
    });
    
    export function Root() {
      return (
        <ApolloProvider client={client}>
          <BookList />
        </ApolloProvider>
      );
    }
    

    Запрашиваем данные хуком useQuery:

    import { gql, useQuery } from '@apollo/client';
    
    const GET_BOOKS = gql`
      query GetBooks {
        books {
          id
          title
          author
        }
      }
    `;
    
    export function BookList() {
      const { data, loading, error } = useQuery(GET_BOOKS);
    
      if (loading) return <p>Загрузка...</p>;
      if (error) return <p>Ошибка: {error.message}</p>;
    
      return (
        <ul>
          {data.books.map((book) => (
            <li key={book.id}>{book.title} — {book.author}</li>
          ))}
        </ul>
      );
    }
    

    Для мутаций есть хук useMutation. Он возвращает функцию-триггер и состояние выполнения:

    const ADD_BOOK = gql`
      mutation AddBook($title: String!, $author: String!) {
        addBook(title: $title, author: $author) {
          id
          title
        }
      }
    `;
    
    const [addBook, { loading }] = useMutation(ADD_BOOK, {
      // Обновляем список после добавления
      refetchQueries: [{ query: GET_BOOKS }],
    });
    

    Частые ошибки

    1. Проблема N+1. Когда резолвер вложенного поля делает запрос к БД на каждом элементе списка. Решение — батчинг через DataLoader, который собирает запросы за один тик и выполняет их одним SQL.

    2. Чрезмерно глубокие запросы. Клиент может запросить user → posts → comments → author → posts... и положить сервер. Ставьте ограничение через graphql-depth-limit или graphql-cost-analysis.

    3. Возврат всей сущности из мутации. Apollo Client автоматически обновит кэш только если в ответе мутации присутствует id и поля, которые уже есть в кэше. Не забывайте возвращать id.

    4. Отсутствие обработки ошибок на резолверах. Бросайте GraphQLError с понятным code в extensions, чтобы клиент мог корректно среагировать.

    5. Использование any в типах. Генерируйте TypeScript-типы из схемы через graphql-codegen — это даст автокомплит и проверку на этапе сборки.

    Заключение

    GraphQL даёт клиенту контроль над формой данных и снимает с бэкенда задачу по поддержке десятка эндпоинтов под разные экраны. Базовый стек прост: схема описывает контракт, резолверы достают данные, Apollo Client на фронте кэширует ответы и предоставляет хуки.

    Для продакшена изучите DataLoader, авторизацию через context, persisted queries и Federation, если у вас несколько сервисов. Начните с маленького сервера, подключите его к React-приложению и постепенно переносите фичи с REST — это самый безболезненный путь миграции.

    Иконка глаза7

    Комментарии

    0

    Постройте личный план изучения Основы Git до уровня Middle — бесплатно!

    Основы Git — часть карты развития Frontend, Backend, DevOps

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Основы JavaScript

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Продвинутый JavaScript

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    TypeScript с нуля

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Картинка поста GraphQL vs REST: когда что выбирать и как перейти
    Иконка аватараАнтон
    Иконка календаря29 мая 2026
    GraphQLRESTAPI+ 1middleИконка уровня middle

    GraphQL vs REST: когда что выбирать и как перейти

    GraphQL vs REST: разбираем ключевые отличия двух подходов к проектированию API, сравниваем производительность и показываем стратегию плавной миграции.

    Иконка чипа0
    Иконка глаза127
    Иконка комментариев0
    Картинка поста Zustand vs Redux: что выбрать для React-проекта в 2025
    Иконка аватараАнтон
    Иконка календаря12 июня 2026
    ReactZustandRedux+ 1middleИконка уровня middle

    Zustand vs Redux: что выбрать для React-проекта в 2025

    Zustand vs Redux в 2025: подробное сравнение производительности, API, бойлерплейта и сценариев использования двух главных решений для управления состоянием в React.

    Иконка чипа0
    Иконка глаза54
    Иконка комментариев0
    Картинка поста WebSocket на Node.js: пишем чат и real-time уведомления
    Иконка аватараАнтон
    Иконка календаря09 июня 2026
    WebSocketNode.jsReal-time+ 1middleИконка уровня middle

    WebSocket на Node.js: пишем чат и real-time уведомления

    WebSocket на Node.js: разбираем протокол, пишем чат на ws-сервере и систему real-time уведомлений с reconnect и heartbeat.

    Иконка чипа+1
    Иконка глаза124
    Иконка комментариев0
    Иконка чипа0