Что такое GraphQL и зачем он нужен

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

«Спрашивай то, что тебе нужно — получишь именно это». Это и есть девиз GraphQL: один запрос, одна точка входа, ровно те данные, что ты просил.

Представь, что ты пришёл в кафе, где меню фиксированное: заказываешь «комплексный обед №3» и получаешь суп, второе, компот и булочку — даже если хотел только второе. Лишнее остаётся на столе, ты за него заплатил, а если захотелось ещё и десерт — иди и делай отдельный заказ. Примерно так работает классический REST: у каждого блюда (ресурса) свой адрес-эндпоинт, и он всегда отдаёт заранее придуманный набор полей.

GraphQL переворачивает идею: вместо десятков фиксированных меню есть один эндпоинт и язык, на котором ты описываешь форму нужного ответа. Хочешь только имя пользователя — попросишь имя. Хочешь имя, аватар и последние три поста за один заход — опишешь это в одном запросе, и сервер вернёт связанные данные единым деревом. GraphQL придумали в Facebook в 2012 году, открыли в 2015-м, а сегодня это зрелый стандарт со спецификацией, который применяют от стартапов до GitHub, Shopify и Netflix.

Ключевая мысль, которую держи в голове весь курс: GraphQL — это не база данных и не замена SQL. Это слой между клиентом и твоими данными. Под капотом сервер всё так же ходит в PostgreSQL, в REST-микросервисы или в файлы — GraphQL лишь даёт клиенту удобный, типизированный, самодокументируемый способ спрашивать.

Как это выглядит на практике

Запрос GraphQL похож на JSON, из которого убрали значения и оставили только ключи. Ты пишешь форму — сервер заполняет её данными:

query {
  user(id: "42") {
    name
    avatarUrl
    posts(last: 2) {
      title
    }
  }
}

А ответ придёт точно такой же формы — это очень удобно, потому что форма запроса предсказуемо повторяет форму ответа:

{
  "data": {
    "user": {
      "name": "Аня",
      "avatarUrl": "https://.../ann.png",
      "posts": [
        { "title": "Мой первый код" },
        { "title": "Как я учила GraphQL" }
      ]
    }
  }
}

Как работает под капотом

Сервер хранит схему — формальное описание всех типов и полей, которые в принципе можно спросить. Когда приходит запрос, сервер: (1) разбирает текст запроса в дерево; (2) проверяет его по схеме — нет ли несуществующих полей; (3) обходит дерево сверху вниз и для каждого поля вызывает функцию-резолвер, которая знает, где взять данные именно этого поля; (4) собирает результаты в JSON. Всю эту цепочку мы разберём по косточкам в следующих разделах — пока достаточно увидеть общую картину:

Клиент              GraphQL-сервер                 Источники данных
  |  query { ... }       |                              |
  | -------------------> |  1. parse (текст -> дерево)  |
  |                      |  2. validate (по схеме)      |
  |                      |  3. execute (резолверы)  ---> БД / REST / кэш
  |  { "data": {...} }   |  4. собрать JSON             |
  | <------------------- |                              |

Чтобы прочувствовать главную идею — «клиент выбирает поля» — поиграй с маленькой моделью прямо в браузере. Тут нет настоящего сервера, только чистая JS-логика выборки полей из объекта:

// Данные на "сервере"
const user = { name: "Аня", age: 19, email: "[email protected]", city: "Казань" };

// Клиент просит ровно эти поля
const requested = ["name", "city"];

function pick(obj, fields) {
  const out = {};
  for (const f of fields) out[f] = obj[f];
  return out;
}

console.log(pick(user, requested));
// { name: "Аня", city: "Казань" } — лишнее (age, email) не приехало

Попробуй сам ▶ — добавь "email" в массив requested и посмотри, как меняется ответ. Это в миниатюре и есть суть GraphQL: форма запроса определяет форму ответа.

Частые ошибки новичка

  • «GraphQL заменит мою базу». Нет. Это транспортный и контрактный слой, данные по-прежнему живут в БД.
  • «Раз эндпоинт один, значит и метод один». Эндпоинт один (обычно /graphql), но операций три: запрос (чтение), мутация (запись) и подписка (поток событий).
  • «GraphQL всегда быстрее REST». Не всегда. Он экономит трафик и круги запросов, но плохо написанные резолверы легко создают проблему N+1 — о ней будет целый урок.

Best practices

  • Думай о GraphQL как о графе своих данных: типы — это узлы, поля-связи — рёбра. Хорошая схема читается как карта предметной области.
  • Не тащи GraphQL в любой проект «потому что модно». Для простого CRUD с одинаковыми клиентами REST часто проще. GraphQL раскрывается там, где много разных клиентов и связанных данных.
  • Начинай с малого: один тип, пара полей, один резолвер. Схему всегда можно расширять — это её сильная сторона.

Итоги

GraphQL — это язык запросов и слой над твоими данными: один эндпоинт, типизированная схема и принцип «клиент сам выбирает поля». Он решает боль REST с лишними и недостающими данными, но не отменяет базу и требует аккуратных резолверов. Дальше мы посмотрим, чем именно он отличается от REST и когда какой подход выбрать.

Проверьте себя
1. Что из перечисленного точнее всего описывает GraphQL?
AБазу данных, заменяющую SQL
BЯзык запросов и слой над данными, где клиент выбирает поля
CФормат файлов вместо JSON
DПротокол транспорта вместо HTTP
2. Почему форму ответа в GraphQL легко предсказать?
AОтвет всегда возвращает все поля типа
BОтвет повторяет форму запроса: какие поля попросил, такие и пришли
CСервер сам решает, что вернуть
DФорма задаётся версией API