Розробка API: REST, GraphQL, WebSocket, tRPC
Клієнт приходить з Postman-колекцією на 200 endpoint'ів і каже: "Все працює, але фронтенд гальмує". Відкриєш вкладку Network — 47 послідовних запитів на загрузку однієї сторінки дашборду. Кожен чекає попередньому. Це не проблема швидкості сервера, це проблема архітектури API.
Коли REST перестає справлятися
REST добре працює для простих CRUD-операцій. Але як тільки у вас появляється мобільний додаток поряд з веб-інтерфейсом, починається over-fetching: мобілка запитує /api/users/123 і отримує об'єкт на 4KB, хоча їй потрібні тільки name та avatar. Помножте на список з 50 користувачів — 200KB трафіку замість 8KB.
GraphQL вирішує це через selection sets. Клієнт описує рівно ті поля, які йому потрібні, і сервер повертає рівно їх. На проекті з React Native + Next.js ми переїхали з REST на Apollo Server: розмір payload на головному екрані додатку впав з 340KB до 28KB без будь-яких змін у backend логіці — тільки схема та резолвери.
Типові болі при впровадженні GraphQL: N+1 query. Резолвер для поля author посту викликає SELECT * FROM users WHERE id = ? для кожного посту в списку. На сторінці з 20 постами — 21 запит до бази. Вирішується через DataLoader — він батчить запити та перетворює їх на один SELECT * FROM users WHERE id IN (...).
tRPC: коли фронтенд та backend на TypeScript
Якщо весь стек на TypeScript (Next.js + Node/Bun), tRPC видаляє цілий шар проблем. Ви визначаєте процедуру на сервері — клієнт отримує повну тайп-безпеку автоматично, без генерації коду та без Swagger. Перейменували поле у схемі Zod — TypeScript підсвітить всі місця на фронтенді, де воно використовується. Це не магія, це просто типи через границю HTTP.
tRPC не підходить, якщо API споживають сторонні клієнти або мобільні додатки на інших мовах. У таких випадках GraphQL або REST з OpenAPI-специфікацією.
WebSocket та реальний час
HTTP-поллінг кожні 5 секунд — це не реальний час. Це ілюзія реального часу з затримкою до 5 секунд та безкорисною нагрузкою на сервер. Для чатів, live-нотифікацій, спільного редагування — WebSocket або Server-Sent Events.
SSE vs WebSocket: SSE — однонаправлений потік від сервера до клієнта, працює поверх звичайного HTTP, автоматично переподключається. Підходить для нотифікацій, стримінгу даних, прогрес-барів довгих операцій. WebSocket — двунаправлений, потрібен для чатів та колаборативних фіч. На практиці 80% задач "реального часу" вирішуються через SSE, а не WebSocket — менше інфраструктурних складностей.
Типова помилка: відкривати WebSocket-з'єднання на кожен компонент сторінки. Бачили проект, де на дашборді відкривалось 12 паралельних WS-з'єднань. Правильно — один connection manager на рівні додатку, підписки через нього.
Swagger / OpenAPI як контракт
Документація, написана постфактум — застаріває на наступний день після релізу. Ми пишемо специфікацію OpenAPI 3.1 до початку розробки, вона стає контрактом між фронтендом та backend'ом. Фронтенд генерує типи через openapi-typescript, backend валідує вхідні дані через згенеровані схеми. Розходження контракту з реалізацією ловиться на CI, а не на review.
Для Laravel — l5-swagger або dedoc/scramble (автогенерація з PHP-анотацій та FormRequest). Для Node.js — @fastify/swagger або Zod + zod-to-openapi.
Аутентифікація API
JWT з довгоживучими access-токенами без ротації — джерело проблем при компрометації. Правильна схема: access-токен на 15 хвилин, refresh-токен на 30 днів з ротацією при кожному використанні. Refresh-токен зберігається в httpOnly cookie, access-токен — у пам'яті (не в localStorage).
Для міжсервісної взаємодії — API Keys з scope-обмеженнями або mTLS. OAuth 2.0 з PKCE для публічних клієнтів (SPA, мобілки).
Версіонування та зворотна сумісність
Ломаючі зміни в API без версіонування ломають клієнтів. Три підходи: URL-версіонування (/api/v2/), заголовок (Accept: application/vnd.api+json;version=2), еволюційне версіонування через додавання полів без видалення старих. Останнє працює для GraphQL — deprecated-директива дозволяє поступово виводити поля з використання.
Процес роботи
Аналіз починається з аудиту поточних інтеграцій та складання схеми даних. Проектуємо API-контракт у OpenAPI або SDL (для GraphQL) — до першої строки коду. Розробка йде за контрактом з автотестами на кожний endpoint. Нагрузкове тестування через k6 перед деплоєм: базовий сценарій — 500 віртуальних користувачів, 10 хвилин, p95 latency не вище 200ms.
Деплой через CI/CD з обов'язковою перевіркою зворотної сумісності (oasdiff для OpenAPI). Документація публікується автоматично з специфікації.
Графік
Розробка API для типового SaaS-проекту з 30–50 endpoint'ами: від 3 до 8 тижнів в залежності від складності бізнес-логіки та кількості зовнішніх інтеграцій. Міграція існуючого REST API на GraphQL — від 2 до 6 тижнів. Додавання WebSocket-шару до готового backend'у — від 1 до 3 тижнів.







