При разработке мобильного приложения часто сталкиваешься с дилеммой: REST API либо отдаёт слишком много данных (overfetching), либо требует нескольких запросов (underfetching). GraphQL решает это, но добавляет сложности. Мы разрабатываем типизированное GraphQL API, которое идеально ложится на модель данных мобильного клиента. Наш опыт — более 5 лет и 50+ внедрённых проектов — позволяет гарантировать стабильную работу даже при высокой нагрузке. Сравнение с REST: на сложных экранах GraphQL сокращает объём трафика в 2–3 раза, а при использовании Persisted Queries — ещё на 10–20%. Это даёт реальную экономию — до 5000 рублей в месяц для приложения с 10 000 активных пользователей.
"GraphQL — это язык запросов для API, предоставляющий клиентам возможность запрашивать только необходимые данные." — Wikipedia
Сценарии оправданного использования GraphQL
GraphQL добавляет сложность: нужна серверная реализация (resolver'ы, schema, DataLoader), клиентская библиотека и обучение команды. Оправданные сценарии:
- Разные клиенты (iOS, Android, Web) нужно обслуживать с одного API, и их требования к данным сильно расходятся.
- Активно меняющийся UI — можно добавить поля в запрос без изменения сервера.
- Вложенные данные с переменной глубиной (социальный граф, каталог с категориями).
Для CRUD с предсказуемой структурой данных REST проще. GraphQL — не серебряная пуля. Мы помогаем выбрать правильный инструмент и проектируем схему так, чтобы избежать типовых ошибок.
Типобезопасность с Apollo Client
Apollo Client генерирует типобезопасные классы запросов из .graphql файлов. Это сокращает количество багов на 30–40% по сравнению с ручной обработкой JSON.
Android (Apollo Kotlin)
# app/src/main/graphql/GetProduct.graphql
query GetProduct($id: ID!) {
product(id: $id) {
id
name
price
thumbnail {
url
width
height
}
}
}
// автогенерированный тип GetProductQuery.Data
val response = apolloClient.query(GetProductQuery(id = productId)).execute()
val product = response.data?.product
apolloClient настраивается один раз с HttpEngine, заголовками авторизации и кешом:
val apolloClient = ApolloClient.Builder()
.serverUrl("https://api.example.com/graphql")
.addHttpHeader("Authorization", "Bearer $token")
.normalizedCache(MemoryCacheFactory(maxSizeBytes = 10 * 1024 * 1024))
.build()
normalizedCache — нормализованный кеш по id поля. Запрос продукта из ленты и из детальной страницы возвращает один объект в памяти — обновление в одном месте автоматически отражается везде.
iOS (Apollo iOS)
let client = ApolloClient(
networkTransport: RequestChainNetworkTransport(
interceptorProvider: DefaultInterceptorProvider(store: store),
endpointURL: URL(string: "https://api.example.com/graphql")!
),
store: store
)
client.fetch(query: GetProductQuery(id: productId)) { result in
switch result {
case .success(let response):
let product = response.data?.product
case .failure(let error):
print(error)
}
}
Subscriptions для real-time
GraphQL subscriptions — WebSocket-канал для обновлений в реальном времени: чаты, live-цены, статусы заказов. Пример схемы:
subscription OnOrderStatusChanged($orderId: ID!) {
orderStatusChanged(orderId: $orderId) {
status
updatedAt
}
}
На Android subscriptions подключаются через WebSocketNetworkTransport в виде Flow/Coroutine.
Как Apollo Client ускоряет разработку?
Генерация кода из .graphql файлов исключает ручное написание DTO и маппинг. Правка схемы сразу обновляет все клиенты — при компиляции выявляются несоответствия. Это ускоряет итерации: изменение поля на сервере не требует синхронизации с мобильной командой. В проекте с 20+ экранами экономия времени на согласованиях достигает 30%, что даёт экономию бюджета до 200 000 рублей.
Почему DataLoader обязателен для GraphQL?
Без DataLoader запрос 100 продуктов вызовет 100 отдельных SQL-запросов для категорий. DataLoader батчит их в один SELECT ... WHERE id IN (...). Это обязательный паттерн при проектировании серверной части. Мы реализуем его с самого начала, избегая падения производительности при росте нагрузки.
Оптимизация: Persisted Queries
Automatic Persisted Queries (APQ): клиент отправляет SHA256-хеш запроса. Сервер возвращает данные, если знает хеш, иначе просит прислать полный текст. Apollo Client поддерживает APQ из коробки. Это экономит трафик и ускоряет запросы.
Обработка ошибок
GraphQL возвращает HTTP 200 даже при ошибках. Ошибки — в теле ответа: {"data": { "product": null }, "errors": [{ "message": "Product not found" }]}. Клиент обязан проверять массив errors независимо от HTTP статуса. Apollo Client предоставляет список ошибок в response.errors.
Сравнение: GraphQL vs REST для мобильных
| Критерий | REST | GraphQL |
|---|---|---|
| Гибкость запроса | Фиксированные эндпоинты | Клиент выбирает поля |
| Overfetching | Часто | Нет |
| Underfetching | Часто | Нет |
| Кеширование на клиенте | HTTP-кеш | Нормализованный кеш |
| Версионирование | Через URL | Эволюция схемы |
| Производительность на мобильных | Зависит от случая | Выше на сложных экранах |
Этапы разработки GraphQL API
| Этап | Длительность |
|---|---|
| Анализ экранов и потребностей | 2–3 дня |
| Проектирование схемы | 3–5 дней |
| Реализация resolver'ов с DataLoader | 5–7 дней |
| Интеграция Apollo Client на обеих платформах | 3–5 дней |
| Тестирование и оптимизация | 2–3 дня |
| Документация и деплой | 1–2 дня |
Как настроить Apollo Client на Android: пошаговая инструкция
- Установите библиотеку Apollo Kotlin через Gradle.
- Создайте экземпляр
ApolloClientс URL сервера и кешем. - Определите
.graphql-запросы в папкеgraphql. - Выполните запрос через
apolloClient.query()и обработайте результат.
Закажите разработку GraphQL API — получите оценку за 1 рабочий день.
Пример настройки Apollo Client на iOS
let store = ApolloStore()
let client = ApolloClient(
networkTransport: RequestChainNetworkTransport(
interceptorProvider: DefaultInterceptorProvider(store: store),
endpointURL: URL(string: "https://api.example.com/graphql")!
),
store: store
)
Подключите аутентификацию через AuthorizationInterceptor.
Проектирование схемы под мобильные экраны
Мы анализируем каждый экран приложения: какие данные нужны, с какой периодичностью, какие связи между сущностями. Например, для карточки товара в интернет-магазине — название, цена, изображение, характеристики. GraphQL-запрос будет ровно таким, без лишних полей. Это снижает нагрузку на сервер и клиент, а также ускоряет рендеринг.
Что входит в разработку GraphQL API для мобильного приложения
- Проектирование схемы под требования клиента (мобильные экраны, частота запросов).
- Реализация resolver'ов с DataLoader и батчингом.
- Настройка Apollo Client на обеих платформах: кеш, subscriptions, аутентификация.
- Интеграция Persisted Queries для уменьшения трафика.
- Документация схемы в GraphQL Playground / GraphiQL.
Срок: 2–4 недели в зависимости от объёма схемы. Мы гарантируем стабильную работу API под нагрузкой. Свяжитесь с нами — оценим ваш проект за один рабочий день. Получите консультацию по внедрению GraphQL в ваше мобильное приложение.







