GraphQL — это язык запросов к API и среда выполнения для выполнения этих запросов, разработанная Facebook в 2012 году и открытая в 2015. В отличие от REST, где сервер определяет структуру ответа, GraphQL позволяет клиенту точно указать, какие данные ему нужны, полностью устраняя проблемы overfetching и underfetching. По данным State of JavaScript Survey (2025), GraphQL используют 35% опрошенных разработчиков, а среди крупных компаний его внедрили GitHub, Shopify, Airbnb и The New York Times. GraphQL поддерживает три типа операций: query (чтение), mutation (запись) и subscription (real-time обновления через WebSocket).
Главное
GraphQL — это спецификация и среда выполнения для API, которая предоставляет клиенту полный контроль над получаемыми данными. Разработанная инженерами Facebook для решения проблем мобильного приложения News Feed, спецификация была опубликована как открытый стандарт в 2015 году. С 2018 года GraphQL находится под управлением GraphQL Foundation при поддержке Linux Foundation и таких компаний, как Apollo, AWS, GitHub, SAP и другие.
В отличие от REST, где каждый эндпоинт возвращает фиксированную структуру данных, GraphQL использует единый эндпоинт, принимающий строку запроса. Клиент описывает в запросе, какие поля ему нужны, и сервер возвращает ровно их. Например, запрос { user(id: "1") { name email } } вернёт только name и email пользователя, без лишних полей вроде address, phone или createdAt, которые пришлось бы получать в REST.
GraphQL не привязан к какой-либо конкретной базе данных или языку. Спецификация определяет только формат запросов и ответов. Существуют реализации серверов на Node.js (graphql-js, Apollo Server), Kotlin (graphql-kotlin, Netflix DGS Framework), Python (Graphene, Strawberry), Ruby (graphql-ruby) и других языках. Клиентские библиотеки доступны для всех основных платформ, включая Apollo Client для iOS, Android и веба.
Архитектура GraphQL состоит из трёх ключевых компонентов: схема (Schema), резолверы (Resolvers) и движок выполнения (GraphQL Engine). Схема определяет, какие типы данных доступны, какие запросы можно выполнять и какие аргументы они принимают. Резолверы — это функции на сервере, которые возвращают данные для каждого поля схемы. Движок выполнения получает входящий запрос, валидирует его по схеме, вызывает соответствующие резолверы и собирает ответ.
Процесс обработки запроса выглядит так:
Ключевое преимущество архитектуры GraphQL — разрешение на уровне полей. В REST разработчик либо получает все поля ресурса (возможно, с лишними), либо прибегает к расширениям вроде ?fields=name,email. В GraphQL такая фильтрация встроена в язык: каждый запрос явно специфицирует, какие поля нужны, и сервер возвращает ровно их. Это особенно важно для мобильных приложений, где объём передаваемых данных напрямую влияет на скорость загрузки и расход трафика.
GraphQL определяет три типа операций, каждый из которых соответствует определённому сценарию взаимодействия. Query — для чтения данных, аналогичен GET в REST. Mutation — для изменения данных (создание, обновление, удаление), аналогичен POST/PUT/DELETE. Subscription — для real-time обновлений через WebSocket, что не имеет прямой аналогии в классическом REST (требует дополнительных решений вроде WebSocket или Server-Sent Events).
Базовый синтаксис запросов интуитивно понятен:
// Простой query с аргументом
query {
user(id: "42") {
name
email
avatarUrl
}
}
// Mutation с возвратом изменённых данных
mutation {
updateProfile(name: "Иван") {
id
name
updatedAt
}
}
// Subscription — слушает real-time обновления
subscription {
newMessage(chatId: "chat_1") {
id
text
sender { name }
}
}
Query выполняется параллельно — все поля на одном уровне загружаются одновременно. Это позволяет загрузить связанные данные (пользователя и его посты) одним запросом без множества round-trip. Mutation выполняется последовательно — мутации в одном запросе выполняются одна за другой в порядке объявления. Subscription устанавливает постоянное соединение через WebSocket, по которому сервер отправляет данные при наступлении события.
Операции могут принимать переменные для отделения данных от запроса, директивы (@include, @skip) для условного включения полей и фрагменты для повторного использования наборов полей. Эти возможности делают GraphQL-запросы гибкими и переиспользуемыми, что особенно важно в крупных проектах с множеством экранов и компонентов.
В основе GraphQL лежит система типов, описывающая все возможные данные и операции API. Схема (Schema) — это описание типов, которые может возвращать сервер, и запросов, которые принимает. Схема пишется на языке Schema Definition Language (SDL) и служит контрактом между клиентом и сервером. Клиент может получить схему через интроспекцию — специальный запрос __schema, который возвращает полное описание API.
Пример схемы для блога:
// SDL — Schema Definition Language
type User {
id: ID!
name: String!
email: String
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String
author: User!
}
type Query {
user(id: ID!): User
posts(page: Int): [Post!]!
}
Восклицательный знак (!) означает non-null поле — оно гарантированно будет присутствовать в ответе. Квадратные скобки [ ] обозначают список. GraphQL поддерживает скалярные типы (Int, Float, String, Boolean, ID), объектные типы, enum, union, interface и input-типы (для аргументов мутаций). Строгая типизация само-документирует API и позволяет клиентским инструментам генерировать код: TypeScript-типы, Kotlin-дата-классы, Swift-структуры.
Интроспекция — уникальная возможность GraphQL, отсутствующая в REST. Клиент может отправить запрос к схеме и получить полное описание всех типов, полей, аргументов и директив. Это лежит в основе инструментов вроде GraphiQL и Apollo Studio, которые автоматически генерируют документацию и автодополнение для разработчиков. Интроспекция также позволяет писать автоматические тесты, проверяющие соответствие схемы ожидаемой структуре.
Выбор между GraphQL и REST — один из ключевых архитектурных вопросов при проектировании API. Оба подхода имеют свои сильные и слабые стороны, и выбор зависит от конкретных требований проекта. REST выигрывает в простоте и универсальности, GraphQL — в гибкости и эффективности запросов. Рассмотрим сравнительную таблицу.
| Критерий | REST | GraphQL |
|---|---|---|
| Структура ответа | Фиксированная, серверная | Гибкая, клиентская |
| Overfetching | Часто — сервер возвращает все поля | Нет — клиент запрашивает только нужные |
| Количество запросов | Множественные round-trips | Один запрос на все данные |
| Кэширование | Нативное HTTP-кэширование | Требует ручной настройки |
| Типизация | Не встроена (зависит от формата) | Строгая, через SDL-схему |
| Инструменты | curl, Postman, Swagger | GraphiQL, Apollo Studio, Introspection |
| Загрузка файлов | Нативно через multipart | Требует дополнительных протоколов |
| Производительность | Предсказуемая, проще оптимизировать | Зависит от сложности вложенных запросов |
Основной недостаток GraphQL — сложность кэширования. В REST HTTP-кэширование работает на уровне URL: один запрос к /api/users/42 возвращает всегда одинаковую структуру, и ответ можно кэшировать по URL. В GraphQL все запросы идут на один эндпоинт, структура ответа зависит от тела запроса. Для решения этой проблемы Apollo Client использует нормализованный кэш на стороне клиента, который разбивает ответы на отдельные сущности по id и автоматически обновляет их при получении новых данных.
Ещё один важный аспект — N+1 проблема. При запросе вложенных данных (например, посты пользователя и комментарии к каждому посту) GraphQL может выполнить отдельный SQL-запрос для каждого элемента списка. Решается с помощью DataLoader — утилиты для батчинга и кэширования запросов к базам данных, которая группирует отдельные запросы в один пакетный. В REST эта проблема менее выражена, так как разработчик контролирует структуру ответа на сервере.
Рассмотрим практические примеры использования GraphQL в мобильном приложении на Kotlin с Apollo Client. Примеры демонстрируют типичные сценарии: загрузка данных для экрана профиля (query), создание нового поста (mutation) и подписка на новые комментарии (subscription). Каждый пример включает как GraphQL-запрос, так и код на клиентской стороне.
Один запрос GraphQL загружает пользователя, его последние посты и общее количество подписчиков. В REST для этого потребовалось бы минимум 2-3 запроса: /users/42, /users/42/posts, /users/42/stats. GraphQL объединяет их в один round-trip, сокращая время загрузки экрана на медленных соединениях.
// GraphQL запрос (в .graphql файле)
query ProfileScreen($userId: ID!) {
user(id: $userId) {
name
bio
avatarUrl
posts(limit: 10) {
id
title
createdAt
}
followersCount
followingCount
}
}
// Вызов на клиенте (Apollo Client + Kotlin)
val response = apolloClient
.query(ProfileScreenQuery(userId = "42"))
.execute()
binding.nameText.text = response.data?.user?.name
Мутация не только создаёт ресурс, но и возвращает его актуальные данные для обновления UI. Поле __typename используется Apollo Client для нормализации кэша — клиент автоматически обновит запись Post в кэше при успешном ответе мутации.
// GraphQL мутация
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
createdAt
author {
id
name
}
}
}
// Вызов мутации с input-типом
val input = CreatePostInput(
title = "Новый пост о GraphQL",
content = "GraphQL упрощает работу с API..."
)
val result = apolloClient
.mutation(CreatePostMutation(input))
.execute()
Важное преимущество GraphQL перед REST в контексте мобильной разработки — автоматическая генерация кода. Apollo Client для Kotlin (Apollo GraphQL) генерирует типобезопасные классы из .graphql файлов на этапе сборки. Если сервер изменит схему, проект не соберётся до обновления запросов. Это предотвращает runtime-ошибки, характерные для REST, где изменение структуры ответа может остаться незамеченным при разработке.
Экосистема GraphQL включает несколько ключевых библиотек и инструментов, которые упрощают разработку и эксплуатацию. Apollo Client — самая популярная клиентская библиотека, поддерживающая React, iOS, Android и Kotlin Multiplatform. Relay от Facebook — альтернатива для React-приложений с уникальным подходом к управлению данными и кэшированием. Выбор между Apollo и Relay зависит от платформы и требований к производительности.
На серверной стороне лидируют Apollo Server (Node.js), Netflix DGS Framework (Kotlin/Java) и graphql-ruby. Для разработки схемы и тестирования запросов используется GraphiQL — интерактивная IDE, встроенная в браузер. Apollo Studio предоставляет метрики производительности, трассировку запросов и управление схемой для продакшн-среды. Отдельно стоит упомянуть GraphQL Code Generator — инструмент, генерирующий TypeScript, Kotlin, Swift и Dart типы из SDL-схемы.
Для мобильной разработки особый интерес представляет Apollo Kotlin (Apollo GraphQL) — библиотека, полностью написанная на Kotlin с поддержкой корутин, Flow и Multiplatform. Она позволяет использовать единые GraphQL-запросы для Android и iOS в Kotlin Multiplatform проектах. Apollo Kotlin нормализует кэш, поддерживает ошибки на уровне полей (partial errors) и автоматически генерирует модели данных из .graphql файлов. Это делает GraphQL предпочтительным выбором для крупных мобильных проектов, где важны скорость разработки и типобезопасность.
Часто задаваемые вопросы
GraphQL не заменяет REST, а предлагает альтернативный подход. REST лучше подходит для простых CRUD-API, кэширования через HTTP и публичных API с предсказуемой нагрузкой. GraphQL оптимален для сложных интерфейсов с множеством связанных данных.
Миграция возможна постепенно: GraphQL может работать как прослойка (gateway) перед существующими REST-сервисами. Многие компании добавляют GraphQL рядом с REST, не отключая старый API. Полная замена требует переписывания резолверов.
N+1 возникает, когда для каждого элемента списка выполняется отдельный запрос к базе данных. Решается с помощью DataLoader — библиотеки, которая батчит отдельные запросы в один и кэширует результаты в рамках одного HTTP-запроса.
Спецификация GraphQL не определяет загрузку файлов напрямую. На практике используются: base64-кодирование (просто, но неэффективно для больших файлов), multipart-запросы по протоколу graphql-multipart-request-spec или отдельный REST-эндпоинт для файлов.
Безопасность GraphQL требует дополнительных мер: ограничение глубины вложенности, лимит сложности запроса, rate limiting на уровне операций. Публичная интроспекция схемы может раскрыть структуру данных — в продакшне её рекомендуется отключать.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также