У цій статті ми розглянемо основні принципи роботи GraphQL і чим він переважає RESTful API у багатьох випадках.
Вебзастосунки постійно ускладнюються: до їхнього складу входить безліч різних елементів, об’єднаних численними API та інтеграціями між клієнтами і серверами. Згодом така ситуація перетворюється на головний біль для розробників: навіть невеликі зміни починають вимагати все більше часу на реалізацію. Потрібно проводити ретельний аналіз, більше тестувати, та однаково є високий ризик виникнення помилок.
Часто єдиним вирішенням цієї проблеми стає рефакторинг інтерфейсів. Однак це дорогий процес, який зазвичай не схвалюється керівництвом без вагомої причини. Менш витратним рішенням може стати GraphQL – інструмент, який пропонує новий підхід до взаємодії між клієнтами та серверами. Це не чарівна паличка, що розв’язує всі проблеми, але він допомагає знайти баланс між повною переробкою застосунку та відсутністю змін.
Що таке GraphQL
GraphQL – це:
- Мова для запитів і зміни даних.
- Середовище виконання для обробки запитів до наявних даних.
GraphQL не слід плутати з SQL – він не використовується для прямих запитів до таблиць бази даних. GraphQL – це, скоріше, формат або структура, яка задає контракт між клієнтом і сервером API. Його можна розглядати як специфікацію або новий стандарт API, схожий на REST, але більш ефективний і гнучкий.
GraphQL спочатку був розроблений як внутрішній проєкт у Facebook приблизно 2012 року. За словами одного з творців, Лі Байрона, концепція GraphQL з’явилася, коли команда намагалася спроєктувати новинну стрічку для iOS з використанням RESTful API. Однак вони одразу зіткнулися з низкою проблем:
- Запити API працювали повільно через мережеві обмеження.
- Координація запитів для різних моделей була ускладнена.
- Доводилося виконувати безліч повторних запитів, що було особливо проблематично на ненадійних мобільних з’єднаннях.
- Зміни в API вимагали ретельного доопрацювання клієнтського коду, щоб застосунок підтримував високе навантаження.
- Документація API часто відставала від фактичної реалізації.
Прагнення подолати ці труднощі при використанні звичайних RESTful API і призвело до створення GraphQL. GraphQL було офіційно випущено 2015 року, а до 2018 року проєкт передали GraphQL Foundation, яка наразі перебуває під управлінням некомерційної організації Linux Foundation.
Як працює GraphQL
Уявіть торговий автомат: щоб витягти з нього якийсь товар, ми натискаємо кнопку і отримуємо один предмет. Щоб отримати другий, потрібно натиснути іншу кнопку. Якщо потрібно 10 предметів, ми натискаємо 10 кнопок.
Це схоже на підхід RESTful API. Для кожної частини даних клієнт має надіслати новий запит. Очевидно, що процес може бути повільним. Як вирішення цієї проблеми розробники створюють спеціальні ендпоінти для надання певних наборів даних. Продовжуючи аналогію, тепер у торгового автомата є спеціальні кнопки, які дозволяють отримати певну комбінацію товарів. Кожна кнопка обслуговує одну конкретну комбінацію. Але проблема зберігається – користувачі можуть бути зацікавлені в сотнях різних комбінацій. Навіть якщо створити сотню кнопок, не можна гарантувати, що клієнту не знадобиться нова унікальна комбінація.
Альтернатива: підхід GraphQL
Тепер уявіть, що автомат дає змогу вибрати кілька товарів за раз, просто вказавши, що саме потрібно. Це і є суть роботи GraphQL:
- Клієнт точно вказує, які дані йому потрібні.
- Сервер GraphQL надає всі запитані дані однією відповіддю.
На відміну від RESTful API, де сервер контролює, які дані надаються, і клієнту часто доводиться надсилати кілька запитів для їхнього збору, GraphQL дає змогу клієнту самому вирішувати, що йому потрібно, заощаджуючи час і ресурси.

Особливості GraphQL
Ці особливості роблять GraphQL потужним інструментом для побудови гнучких, зрозумілих і передбачуваних API.
Декларативність
У GraphQL клієнти надсилають запити серверу, які мають декларативний характер. У цьому прикладі клієнт запитує книгу з ідентифікатором id = «1» і вказує, що йому потрібні тільки поля title і publicationYear. Сервер GraphQL зобов’язаний повернути тільки ті дані, які були запитані.
Ієрархічність
GraphQL дозволяє легко описувати ієрархічні зв’язки між даними. Сервер повертає відповідь, що відображає ці залежності, в одній структурі. У цьому запиті клієнт запитує книгу з id = «1», але крім цього цікавиться інформацією про авторів книги.
Типобезпека
Типобезпека – ще одна важлива особливість GraphQL. Для роботи в GraphQL необхідно оголошувати схеми, які описують моделі даних. Схема дає змогу серверу перевіряти, чи коректний запит клієнта. Усі схеми строго типізовані. Типова система підтримує як прості типи даних (числа, рядки, булеві значення), так і складні типи, наприклад, об’єкти.
Основні концепції GraphQL
GraphQL охоплює кілька ключових концепцій.
Мова визначення схем
Синтаксис, який використовується для опису схеми, відомий як мова визначення схем (SDL). Ця схема описує тип Author, у якого є тільки одне поле – name. Символ ! вказує, що поле обов’язкове для заповнення.
Запити
Запити – ймовірно, найважливіше поняття в GraphQL. Клієнти надсилають серверу запити, які описують, які дані їм потрібні. Якщо запит валідний, сервер повертає відповідь. У цьому запиті клієнт запитує книгу з id = «1» і хоче отримати тільки її назву та ціну.
Мутації
API використовуються не тільки для отримання інформації, а й для її оновлення. У GraphQL оновлення виконуються за допомогою мутацій.
Підписки
У сучасних застосунках часто важливо підтримувати з’єднання між сервером і клієнтом, щоб клієнт миттєво отримував повідомлення про події. Для цього використовуються підписки. Підписки відрізняються від типового циклу «запит-відповідь». Клієнт підписується на подію і підтримує з’єднання із сервером. Коли подія відбувається, сервер надсилає дані клієнту. Після того як клієнт відправляє підписку, з’єднання між клієнтом і сервером залишається відкритим. Коли створюється новий автор, сервер надсилає дані клієнту.
Приклад використання GraphQL
Тепер, коли ми розібралися з особливостями і концепціями GraphQL, нумо подивимося, як це працює на практиці – створимо простий сервер GraphQL API. Для налаштування сервера GraphQL API потрібні три основні компоненти:
- Вебсервер. Як сервер ми будемо використовувати Express, популярний фреймворк для створення API, що працює в середовищі NodeJS.
- Схема GraphQL з резолвером. Схема і резолвери будуть реалізовані за допомогою пакета graphql – стандартної реалізації GraphQL для JavaScript.
- Обробник запитів. Для обробки запитів ми будемо використовувати пакет express-graphql, який виступає в ролі проміжного ПЗ для Express.
Підготовка проєкту
Створіть папку для проєкту і встановіть необхідні пакети (припускається, що NodeJS уже встановлено).
Створення сервера
Створіть файл server.js і збережіть у ньому наступний код:
Код працює так:
- Імпортуємо express, express-graphql і graphql.
- Використовуємо функцію buildSchema(), щоб створити просту схему, де визначено запит hello, що повертає рядок.
- Резолвер для запиту hello повертає рядок «Hello, World».
- Використовуємо метод app.use(), щоб налаштувати graphqlHTTP, який обробляє запити GraphQL, використовуючи нашу схему і резолвер.
- У GraphQL API є тільки одна кінцева точка /graphql. Усі запити обробляються через неї (на відміну від REST, де у кожного ресурсу є власний ендпойнт).
- Встановлення прапора graphiql: true вмикає графічний інтерфейс GraphiQL, що дає змогу надсилати запити та бачити їхні результати.
Запуск сервера
Після запуску сервера можна відкрити http://localhost:4000/graphql у браузері:

Порівняння GraphQL і REST
REST довгий час був стандартом в індустрії, проте обмежена гнучкість робить його менш придатним для сучасних додатків із мінливими вимогами. GraphQL має низку переваг перед REST.
Надлишкове завантаження даних
- Проблема REST: у ендпойнтів є фіксований формат відповіді. Навіть якщо клієнту потрібно тільки одне поле, API повертає весь набір даних, що призводить до надлишкового завантаження.
- GraphQL дає змогу клієнту запросити тільки ті поля, які йому потрібні. Це значно скорочує обсяг зайвих даних.
Нестача даних
- Проблема REST: часто один REST-ендпойнт не надає всієї інформації, яка потрібна клієнту. Наприклад, для отримання книги та інформації про автора потрібно кілька запитів. Це явище називається проблемою n+1.
Клієнт виконує один запит, отримує частину даних, а потім робить додаткові запити, щоб отримати інформацію, що залишилася.
- У GraphQL можна отримати всі необхідні дані в одному запиті завдяки ієрархічним запитам. Наприклад, можна запросити одночасно інформацію про книгу і про автора.
Зниження мережевого трафіку
- Проблема REST: множинні запити в REST збільшують мережевий трафік, особливо якщо застосунок працює на повільному або нестабільному з’єднанні.
- GraphQL значно знижує навантаження на мережу, оскільки дає змогу передавати всі необхідні дані одним запитом.
Покращена аналітика
- Проблема REST: сервер не знає, які поля з відповіді, що повертається, дійсно використовуються клієнтом. Сервер просто відправляє всі дані і забуває про запит.
- У GraphQL клієнти формують чіткі запити, вказуючи, які поля їм потрібні. Це дає серверам можливість аналізувати вхідні запити, розуміти поведінку клієнтів і оптимізувати структуру даних у майбутньому.
Архітектурні шаблони GraphQL
На високому рівні GraphQL слідує класичній клієнт-серверній архітектурі: клієнт надсилає запит, сервер обробляє його і повертає відповідь. Однак усередині цієї моделі можливі кілька варіацій.
GraphQL-сервер із підключеною базою даних
Цей шаблон ідеально підходить для нових проєктів:
- Існує один вебсервер, який реалізує специфікацію GraphQL.
- Сервер приймає запити, обробляє їх і повертає відповіді.
- Сервер підключається до бази даних (наприклад, MySQL, MongoDB або AWS Aurora).
Переваги:
- Простота реалізації запитів до даних.
- Мінімальна затримка завдяки близькості даних до сервера.
- Ідеальний для нових проєктів, де вся архітектура створюється з нуля.
Обмеження:
- Не підходить для наявних застосунків, де вже є усталені системи або сервіси.
GraphQL-шар для наявних систем
Якщо застосунок уже використовує сторонні API, застарілі системи або різнорідні мікросервіси, GraphQL можна використовувати як об’єднуючий шар:
- GraphQL виступає в ролі прошарку, що приховує складність наявних систем.
- Клієнти взаємодіють тільки з GraphQL API, не знаючи про складнощі реалізації запитів.
- Сервер GraphQL відправляє запити до різних джерел (API, сервісів, баз даних) і об’єднує відповіді.
Переваги:
- Спрощення взаємодії для нових клієнтів.
- Збереження наявної логіки та систем.
- Можливість поступово інтегрувати нові рішення.
Обмеження:
- Складність реалізації, оскільки сервер GraphQL має вміти обробляти запити до різних джерел даних.
Гібридний підхід
Цей підхід поєднує елементи двох попередніх – підключену базу даних і взаємодію з наявними системами:
- Сервер GraphQL може отримувати дані з бази даних або надсилати запити в застарілі системи та сервіси.
- Це дає змогу поступово мігрувати бізнес-логіку із застарілих систем у GraphQL.
Переваги:
- Підходить для великих застосунків, де потрібна інтеграція нових рішень з наявними системами.
- Спрощує повільний перехід від застарілих систем до більш сучасних.
Обмеження:
- Вимагає ретельного планування та реалізації, щоб підтримувати стабільність системи.
Переваги та недоліки GraphQL
Зіставлення плюсів і мінусів допоможе вирішити, чи потрібен GraphQL вашому проєкту або краще обійтися REST API.
Переваги GraphQL:
- Клієнт може отримувати тільки ті дані, які йому потрібні.
- Типізація й автоматична валідація дає змогу клієнтам легко зрозуміти, які дані й типи доступні в API, і точно формулювати запити.
- Клієнти не залежать від серверних змін у структурі даних.
Недоліки GraphQL:
- Можливі проблеми з продуктивністю. Підтримка ієрархічних запитів із глибокими рівнями вкладеності може призвести до проблем із продуктивністю. Щоб їм запобігти, варто впровадити ліміти на кількість вкладених рівнів або обмеження частоти запитів.
- Для невеликих і простих додатків функціональність GraphQL може бути зайвою.
- GraphQL не підтримує кешування на рівні HTTP. Це може призвести до збільшення навантаження на сервер, оскільки кожен запит буде виконуватися заново, а не витягуватися з кешу.
На закінчення
GraphQL пропонує більшу гнучкість і контроль для клієнтів, але водночас вимагає уважного підходу до архітектури та продуктивності програми. У той час як для великих і складних систем GraphQL може бути чудовим вибором, REST API, як і раніше, є простішим і більш підходящим рішенням для невеликих проєктів.