Перейти к содержанию
Innovialabs

Что такое GraphQL и как он работает

Основы3 мин

Коротко

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

Что такое GraphQL

GraphQL — это язык запросов к API и среда выполнения на сервере. Его создали в Facebook для мобильных приложений и открыли в 2015 году.

Главная идея: клиент сам говорит, какие данные ему нужны. Вместо десятка эндпоинтов вроде /users/1, /users/1/orders есть один адрес (обычно /graphql), куда отправляется запрос с описанием нужной формы ответа. Сервер возвращает JSON ровно этой формы.

Какие проблемы он решает

  • Over-fetching — эндпоинт отдаёт больше полей, чем нужно экрану. На мобильном интернете это лишний трафик.
  • Under-fetching — для одного экрана приходится делать несколько запросов подряд: пользователь, потом его заказы, потом товары.
  • Разные клиенты — разные потребности. Веб, iOS и Android хотят разные наборы полей, и бэкенду приходится плодить версии эндпоинтов.
  • Нет единого контракта. В GraphQL схема обязательна и всегда описывает, что доступно.

Схема

Схема — это контракт между клиентом и сервером. Она пишется на SDL (Schema Definition Language):

type User {
  id: ID!
  name: String!
  orders: [Order!]!
}

type Order {
  id: ID!
  total: Float!
  status: String!
}

type Query {
  user(id: ID!): User
}

type Mutation {
  createOrder(userId: ID!, total: Float!): Order!
}

type Subscription {
  orderStatusChanged(orderId: ID!): Order!
}

! означает, что поле не может быть null. [Order!]! — обязательный список обязательных элементов.

Запросы (Query)

Запрос на чтение данных. Клиент выбирает поля, включая вложенные:

query {
  user(id: "1") {
    name
    orders {
      id
      total
    }
  }
}

Ответ повторяет форму запроса:

{
  "data": {
    "user": {
      "name": "Алия",
      "orders": [{ "id": "10", "total": 250000 }]
    }
  }
}

Пользователь и его заказы пришли за один запрос, без лишних полей.

Мутации (Mutation)

Мутации изменяют данные: создают, обновляют, удаляют. После изменения можно сразу запросить нужные поля результата:

mutation {
  createOrder(userId: "1", total: 99000) {
    id
    status
  }
}

Подписки (Subscription)

Подписки дают обновления в реальном времени. Клиент подписывается на событие, а сервер присылает данные, когда оно происходит. Обычно работают поверх WebSocket. Подходят для статусов заказов, уведомлений, чатов.

Резолверы

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

const resolvers = {
  Query: {
    user: (_, { id }) => db.users.findById(id),
  },
  User: {
    orders: (user) => db.orders.findByUserId(user.id),
  },
};

Сервер разбирает запрос, проверяет его по схеме и вызывает резолверы только для запрошенных полей. Данные могут приходить из базы, другого API или кэша — клиенту это не важно.

Что важно знать на практике

  • Проблема N+1. Если запросить список из ста пользователей с заказами, наивный резолвер сделает сто отдельных запросов к базе. Решение — батчинг, например через библиотеку DataLoader.
  • Кэширование сложнее. Все запросы идут через POST на один адрес, поэтому HTTP-кэш работает хуже, чем в REST. Используют клиентский кэш (Apollo Client, urql) и persisted queries.
  • Защита от тяжёлых запросов. Нужно ограничивать глубину и сложность запросов, иначе клиент может запросить огромное вложенное дерево.
  • Ошибки. Ответ часто приходит с HTTP 200, а ошибки лежат в поле errors. Мониторинг надо настраивать с учётом этого.
  • Интроспекция. Схему можно запросить у сервера, на этом построены инструменты автодополнения и генерации типов.

Официальная документация: graphql.org.

Частые вопросы

Нет. GraphQL — слой API между клиентом и любыми источниками данных. За ним может стоять PostgreSQL, MongoDB, REST-сервисы или всё сразу.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.