Гайды

Основы GraphQL: схема и резолверы

SDL, query и mutation, резолверы и N+1, подписки, Apollo Server и экосистема Python Strawberry/Ariadne.

~10 мин чтения

Основы GraphQL: схема и резолверы

GraphQL — язык запросов к API: клиент описывает форму дерева данных, сервер выполняет резолверы полей и возвращает JSON. Спецификация независима от языка; в экосистеме Node часто встречается Apollo Server, в Python — Strawberry, Ariadne, Graphene. Этот гайд про схему, типы и резолверы на концептуальном уровне; сравнение с REST — GraphQL vs REST.


1. Схема (Schema SDL)

graphql
type Query {
  book(id: ID!): Book
  books(limit: Int = 10): [Book!]!
}

type Book {
  id: ID!
  title: String!
  author: Author!
}

type Author {
  id: ID!
  name: String!
  books: [Book!]!
}

! — non-null; [Book!]! — список не null, элементы не null, сам список не null.


2. Запрос (query)

graphql
query {
  book(id: "42") {
    title
    author {
      name
    }
  }
}

Один HTTP-запрос, ровно те поля, что запрошены (в пределах разрешённой схемы).


3. Резолверы

Для каждого поля может быть функция (parent, args, context, info) -> value.

  • Корневые поля Query / Mutationparent часто None.
  • Вложенныеparent — объект родителя (например Book для поля author).

N+1 проблема: для списка книг поле author может вызвать резолвер на каждую книгу → storm запросов к БД. Решения: DataLoader (батчинг + кэш на запрос), join на уровне ORM, ограничение глубины запросов.


4. Мутации (mutation)

graphql
mutation {
  createBook(title: "GraphQL intro") {
    id
    title
  }
}

Изменения данных — явно отделены от чтения в протоколе (хотя технически query тоже может иметь side effects — антипаттерн).


5. Подписки (subscription)

Долгоживущее соединение (часто WebSocket) для push-событий. Требует инфраструктуры pub/sub за сервером. В FastAPI — WebSockets в документации.


6. Apollo Server (ориентир Node)

  • Построение схемы из SDL + resolvers map.
  • Plugins: логирование, ошибки, persisted queries.
  • Интеграция с federation для микросервисных схем.

Для Python-проекта смотрите Strawberry (аннотации типов) или Ariadne (schema-first).


7. Кастомные скаляры и ошибки

scalar DateTime / URL / Money задают контракт сериализации: serialize → JSON, parseValue ← вход клиента. Не смешивайте «сырой» ISO-строковый String там, где нужна валидация формата.

Ошибки в GraphQL часто приходят массивом в errors[] при HTTP 200 — для клиентов удобны extensions.code, trace_id для связи с логами; не отдавайте полный Python/Java stack trace наружу в production.


8. Валидация и авторизация

  • Валидация аргументов — в резолвере или через directives / middleware.
  • Авторизация — в context кладут пользователя после JWT; резолверы проверяют права — см. JWT в FastAPI.
  • Introspection в проде часто отключают или ограничивают (сканирование схемы).

9. Чек-лист

  • Ограничение сложности/глубины запросов (cost analysis).
  • DataLoader или эквивалент против N+1.
  • Отдельные типы для публичного API vs внутренних моделей БД.
  • Версионирование схемы (deprecated fields) вместо ломки клиентов.

Дальше: GraphQL vs REST · тег GraphQL