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, де кожен endpoint повертає фіксовану структуру даних, GraphQL використовує єдиний endpoint, який приймає рядок запиту. Клієнт описує в запиті, які поля йому потрібні, і сервер повертає саме їх. Наприклад, запит { 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 всі запити йдуть на один endpoint, структура відповіді залежить від тіла запиту. Для вирішення цієї проблеми 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також