GraphQL на сервере: схема, типы, resolvers

↑ 5.3 GraphQL на бэкенде и Federation · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Ждут понимания, чем GraphQL отличается от REST и где он оправдан.

Объяснение

GraphQL — язык запросов и рантайм: клиент сам описывает нужную форму данных, сервер отвечает ровно ей через один endpoint (POST /graphql).

type Query { order(id: ID!): Order  orders(first: Int, after: String): OrderConnection! }
type Mutation { cancelOrder(id: ID!): Order! }
type Subscription { orderUpdated(id: ID!): Order! }
 
type Order { id: ID!  number: String!  customer: Customer!  items: [Item!]!  total: Decimal! }
ПонятиеСмысл
Schemaстрого типизированный контракт
Query / Mutation / Subscriptionчтение / изменение / поток событий
Resolverфункция, получающая значение поля
Scalar, Enum, Interface, Union, Inputтипы

Клиент запрашивает только нужное:

query { order(id: "42") { number customer { name } items { title price } } }
ПлюсыМинусы
нет over/under-fetchingсложнее кэширование HTTP
один запрос вместо несколькихN+1 в resolvers
самодокументируемая схеманужны лимиты сложности
удобно для разных клиентов (web, mobile)больше инфраструктуры

Resolvers выполняются на каждом поле: поле customer вызовет свой resolver для каждого заказа — источник N+1 (см. Проблема N+1 и DataLoader).

Нюансы и подводные камни

  • Всегда 200 OK: ошибки лежат в поле errors, а не в HTTP-статусе.
  • Схема — публичный контракт: устаревшие поля помечайте @deprecated, не удаляйте.
  • Не отдавайте сущности БД как есть: проектируйте схему вокруг клиентов.
  • Авторизация — на уровне полей и типов, а не только endpoint.
  • GraphQL не заменяет REST везде: для простых CRUD и публичных API REST проще.

Практика

  1. Опишите схему магазина и запросите вложенные данные одним запросом.
  2. Найдите N+1 в логах SQL.
  3. Сравните число запросов клиента для REST и GraphQL на экране заказа.

Вопросы с ответами

Связанные темы