Разработка серверной части (Backend) для мобильного приложения на 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. При пиковой нагрузке (запуск приложения после маркетинговой кампании, массовые пуши) сервер не начинает «захлёбываться» в очереди потоков.
Предсказуемый 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, иначе каждый пуш открывает новый 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; пуши — только через очередь (Redis Streams или RabbitMQ)
-
Игнорирование
context.Contextотмены — при дисконнекте мобильного клиента запрос к БД должен отменяться, иначе накапливаются висящие транзакции







