Розробка Go бекенду для мобільних додатків
Go вибирають для мобільного бекенду не з моди — а коли REST API починає «не тягнути» на 5000+ одночасних з'єднань, а Node.js-моноліт вже вимагає горизонтального масштабування на кожні 200 rps. Горутини та вбудований scheduler дозволяють обслуговувати тисячі з'єднань на одному інстансі без thread pool overhead, що критично для push-heavy додатків та стрімінгу.
Чому Go, а не Node чи Python, коли позаду мобільний клієнт
Мобільний клієнт нетерпеливий. iOS закриває URLSession через 60 секунд, Android OkHttp за умовчанням — через 30. Якщо бекенд повільно видає список новин або користувацький фід, клієнт отримає NSURLErrorTimedOut або SocketTimeoutException, а не дані.
Go вирішує кілька конкретних болей:
Латентність під навантаженням. net/http обробляє кожен запит у окремій горутині, вартість якої ~2KB памяті проти ~1MB у OS thread. При піковому навантаженні (запуск додатка після маркетингової кампанії, масові push) сервер не починає «захлипуватися» в чергу потоків.
Передбачуваний GC. Починаючи з Go 1.14 паузи GC не перевищують 0.5ms у більшості production-сценаріїв — це важливо, коли мобільний клієнт робить polling кожні 15 секунд та чутливий до jitter.
Компільований бінарник без рантайму. Docker-образ з Go-сервісом важить 15–25 MB. Це прискорює cold start у Kubernetes при автоскейлингу — новий pod стартує за 2–3 секунди замість 20–30 у JVM-додатків.
Як будуємо API для мобільного клієнта
Основний стек: Gin або Echo для HTTP-маршрутизації, sqlx або pgx для роботи з PostgreSQL, go-redis для кешування сеансів та rate limiting, zap для структурованих логів.
Для автентифікації мобільного клієнта реалізуємо JWT з refresh-token rotation: access token живе 15 хвилин, refresh — 30 днів. При переведенні refresh-токена старий інвалідуємо через Redis-set з TTL. Це важливо, бо мобільні додатки не можуть використовувати httpOnly cookie так само надійно, як веб — токени зберігаються в Keychain/Keystore.
Приклад реального рішення: додаток для доставки їжі з 80 000 DAU. API-сервер на Go (Echo v4) обробляв endpoint /orders/active — агрегацію з трьох таблиць PostgreSQL з JOIN'ами. Перша версія на Node.js давала p99 = 450ms при 500 rps. Після переносу на Go з connection pool через pgxpool та батч-запитами: p99 = 35ms при тому ж трафіку. Інфраструктура — той же Kubernetes-кластер, ті ж два пода.
Структура проекту
Дотримуємось layout з golang-standards/project-layout:
/cmd/api — точка входу, ініціалізація DI
/internal — бізнес-логіка (handlers, services, repository)
/pkg — переиспользуемі утиліти
/migrations — SQL-міграції (goose або golang-migrate)
Репозиторний шар — інтерфейси. Тести не мокують HTTP — тільки repository-інтерфейс. Це дозволяє покрити бізнес-логіку unit-тестами без піднімання БД.
Інтеграції, які потрібні мобільному бекенду
-
Firebase Cloud Messaging — через офіційний
firebase-admin-goSDK, батч-відправка до 500 токенів за раз -
Apple Push Notification Service — через
apns2з HTTP/2 connection pool, інакше кожен push відкриває новий TLS-хендшейк - S3-сумісне сховище (AWS S3, MinIO) — для користувацьких медіа, presigned URL для прямого завантаження з клієнта
- Stripe / CloudPayments — webhook-обробники з idempotency key для безпечного retry
Процес роботи
Починаємо з аудиту вимог: нагрузкові профілі (rps, p99-latency SLA), інтеграції з третіми сервісами, регуляторні вимоги до зберігання даних. Потім — проектування схеми БД та API-контракту (OpenAPI 3.0). Розробка з покриттям ключових сценаріїв тестами (testing + testify). Деплой — Docker + Kubernetes, CI через GitHub Actions або GitLab CI.
Терміни залежать від числа ендпоінтів та інтеграцій: простий API (10–15 методів, одна БД) — 3–5 тижнів; сервіс з реалтаймом (WebSocket/SSE), кількома інтеграціями та аналітикою — 8–14 тижнів.
Типові помилки на Go-бекенді для мобайла
- Відсутність rate limiting на рівні IP + user — мобільний клієнт при поганому з'єднанні робить retry у цикліі, без обмежень це вбиває БД
-
database/sqlбез явногоSetMaxOpenConns— за умовчанням ліміт з'єднань необмежений, при піку отримуєтеconnection refusedвід PostgreSQL - Синхронна відправка push у HTTP-handler — FCM/APNs можуть відповідати 200–500ms, це блокує горутину та збільшує latency; push-и — тільки через чергу (Redis Streams або RabbitMQ)
-
Ігнорування
context.Contextвідміни — при дисконнекті мобільного клієнта запит до БД має відмінятися, інакше накопичуються висячі транзакції







