GraphQL: query, mutation, subscription, fragments
↑ 5.4 Работа с API: REST, GraphQL, WebSocket · ← Предыдущая · → Следующая
Зачем это на собесе
Клиентская сторона 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 |
| Aliases | a: 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.
- Избыточные запросы вложенности → тяжёлые запросы; ограничения на сервере.
- Ошибки на уровне полей приходят вместе с данными.
Практика
- Напишите запрос с переменными и фрагментом, выполните через
graphql-request. - Подключите подписку через
graphql-ws. - Сравните нормализованный кэш Apollo и кэш по ключам Vue Query.
Вопросы с ответами
Чем query отличается от mutation?
Query — чтение, поля выполняются параллельно; mutation — изменение, поля выполняются последовательно.
Зачем фрагменты?
Переиспользование наборов полей и colocation данных с компонентами.