GraphQL: query, mutation, subscription, fragments

↑ 5.4 Работа с API: REST, GraphQL, WebSocket · ← Предыдущая · → Следующая

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

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

Клиентская сторона GraphQL: как писать запросы, использовать фрагменты и переменные.

Объяснение

Серверная часть — в GraphQL на сервере: схема, типы, resolvers. Клиент отправляет POST /graphql с { query, variables, operationName }.

query GetOrder($id: ID!, $withItems: Boolean = false) {
  order(id: $id) {
    ...OrderFields
    items @include(if: $withItems) { sku qty }
  }
}
fragment OrderFields on Order { id number status total customer { id name } }
 
mutation CancelOrder($id: ID!) { cancelOrder(id: $id) { ...OrderFields } }
 
subscription OnOrderUpdated($id: ID!) { orderUpdated(id: $id) { id status } }
ПонятиеСмысл
Queryчтение, параллельное выполнение полей
Mutationизменение, последовательное выполнение
Subscriptionпоток событий (WebSocket/SSE)
Variablesпараметры вместо конкатенации строк (безопасность и кэш плана)
Fragmentsпереиспользуемые наборы полей; colocation с компонентом
Directives@include, @skip, @defer, @stream, клиентские @client
Aliasesa: order(id: 1) b: order(id: 2)
Inline fragments, unions... on Photo { url }
Introspectionполучение схемы (генерация типов)
__typenameтип объекта для нормализованного кэша
// graphql-request + Vue Query
const client = new GraphQLClient("/graphql", { headers: () => ({ Authorization: `Bearer ${token()}` }) });
const { data } = useQuery({ queryKey: ["order", id], queryFn: () => client.request(OrderDocument, { id: id.value }) });

Клиенты: Apollo Client (нормализованный кэш, @vue/apollo-composable), urql, graphql-request + Vue Query (проще, кэш по ключам). Нормализованный кэш по __typename:id автоматически обновляет одну сущность везде, где она показана.

Ошибки: HTTP 200 с полем errors (и, возможно, data частично) — обрабатывайте оба.

Подписки: graphql-ws; переподключение и повторная авторизация.

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

  • Нельзя конструировать запрос конкатенацией: используйте переменные.
  • Кэширование HTTP затруднено (POST): нужны persisted queries/GET.
  • Фрагменты «скрывают» зависимости: организуйте colocation и codegen.
  • Избыточные запросы вложенности → тяжёлые запросы; ограничения на сервере.
  • Ошибки на уровне полей приходят вместе с данными.

Практика

  1. Напишите запрос с переменными и фрагментом, выполните через graphql-request.
  2. Подключите подписку через graphql-ws.
  3. Сравните нормализованный кэш Apollo и кэш по ключам Vue Query.

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

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