Когда клиент приходит с готовым дизайном мобильного приложения и просит просто подключить бэкенд, я сначала уточняю: API под него вообще спроектировано? Разработка API для мобильного приложения начинается не с эндпоинтов, а с вопросов - сколько платформ обслуживает один бэкенд, как клиент ведёт себя в офлайне, кто отвечает за пуши и как версии приложения в сторах будут жить рядом с обновлениями сервера. Если заложить это до старта, релизы проходят спокойно. Если нет, через полгода начинаются костыли под старые версии APK и разбор багов на проде поздним вечером.
Архитектура API для мобильного приложения: REST, GraphQL или гибрид
Первый вопрос на старте проекта - что именно дёргает бэкенд: один экран с плоским списком заказов или дашборд с вложенными сущностями вроде «заказ - позиции - отзывы - статус доставки». Для простых CRUD-сценариев REST закрывает большинство задач и понятен любому разработчику, который придёт на проект после меня. GraphQL оправдан, когда мобильный клиент собирает данные из трёх-четырёх разных сущностей на одном экране и важно гонять по сети минимум байт - это критично для приложений с нестабильным покрытием сети в регионах.
На практике для интернет-магазинов и сервисов с доставкой я беру REST с чётким разделением на ресурсы: /orders, /products, /users, /delivery. Для мобильных дашбордов с аналитикой, где на одном экране собирается статистика из пяти таблиц, GraphQL экономит клиенту 3-4 отдельных запроса и упрощает жизнь фронтенд-разработчику мобильного приложения.
| Критерий | REST | GraphQL |
|---|---|---|
| Число запросов на сложный экран | 3-5 отдельных вызовов | 1 запрос с нужными полями |
| Кэширование ответов на CDN и прокси | Из коробки, по URL | Требует отдельной настройки |
| Порог входа для команды | Низкий | Выше, нужна схема и резолверы |
Если под задачу нужен бэкенд с нуля, я обычно веду такую разработку API и бэкенда на Laravel: фреймворк даёт готовую авторизацию, очереди для фоновых задач и предсказуемую структуру, которую легко передать другой команде при масштабировании проекта.
Аутентификация и токены в бэкенде для мобильного клиента
Мобильное приложение живёт не в браузере, поэтому классические сессионные куки для него неудобны: приложение может месяцами не закрываться, а токен должен обновляться без участия пользователя. Я закладываю связку access-токен на 15-30 минут и refresh-токен на 30-60 дней, который хранится на устройстве в Keychain на iOS и Keystore на Android. Бэкенд отвечает за ротацию refresh-токенов при каждом обновлении и за таблицу активных сессий по device_id - без неё невозможно сделать нормальную кнопку «выйти со всех устройств», которую рано или поздно просит заказчик после жалобы пользователя на утерянный телефон.
Если в приложении есть вход через Apple ID или Google, id_token с клиента обязательно валидируется на сервере через публичные ключи провайдера - доверять данным, которые пришли напрямую от клиента без проверки подписи, нельзя ни при каких условиях.
| Способ | Отзыв доступа | Подходит для мобильного клиента |
|---|---|---|
| JWT access + refresh | По списку сессий в базе | Да, стандарт для мобильных API |
| Сессионные cookie | Мгновенный, через сервер | Плохо, завязано на браузерные куки |
| Статичный API-ключ | Только полная замена ключа | Нет, риск компрометации |
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Версионирование и обратная совместимость мобильного API
Сайт можно обновить и через минуту все пользователи увидят новую версию. С мобильным приложением так не работает: часть пользователей неделями сидит на старой версии из App Store или Google Play, потому что не обновляет приложение или отключила автообновления. Поэтому в бэкенд закладываю версионирование через путь: /api/v1/orders, /api/v2/orders, а не через заголовки - так проще дебажить по логам, какая версия клиента дёргает эндпоинт.
Старую версию я держу живой минимум 6-9 месяцев после релиза новой - это реалистичный срок, за который основная масса пользователей обновит приложение сама. Форсировать обновление стоит только когда меняется формат критичных данных, например схема оплаты, и через отдельный эндпоинт проверки минимальной поддерживаемой версии на старте приложения.
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json" \
https://api.example.ru/v2/orders/1234
Ещё один момент, который экономит недели на старте: контракт API в формате OpenAPI я готовлю до того, как бэкенд полностью реализован. Мобильная команда пишет клиент на моках по этому контракту, а бэкенд параллельно реализует эндпоинты - вместо того чтобы фронтенд ждал готовый сервер.
Пуши, вебхуки и фоновые задачи в бэкенде мобильного приложения
Отправка пуша через FCM или APNs не должна выполняться внутри запроса, который отвечает мобильному клиенту - иначе при просадке у Google или Apple зависает и весь остальной API. Я выношу отправку push-уведомлений в очередь: запрос от клиента отрабатывает за миллисекунды, а воркер разбирает очередь и рассылает уведомления отдельно, с ретраями при таймауте у провайдера.
Тот же принцип для входящих вебхуков от платёжных систем и служб доставки: сначала быстро принимаю и сохраняю сырое событие, отвечаю провайдеру 200 OK, а обработку веду уже в фоне. Для внутренней маршрутизации таких событий - например, отправить уведомление в рабочий чат при неудачном платеже - удобно поднять сценарий в n8n, не размазывая эту логику по коду бэкенда. Критичные ошибки на проде я обычно завожу в отдельный Telegram-канал команды, иногда через простого aiogram-бота, чтобы разработчик увидел проблему раньше, чем о ней напишет пользователь в поддержку.
Платежи, доставка и внешние интеграции в API мобильного приложения
Если в приложении есть оплата, эквайринг вроде T‑Bank требует от бэкенда, а не от мобильного клиента, инициировать платёж и хранить идемпотентный ключ операции - без него повторный тап пользователя по кнопке «Оплатить» при плохой связи рискует создать два списания. Обработка callback от банка идёт по тому же принципу, что и вебхуки: подпись проверяется на сервере, статус заказа обновляется, а мобильному клиенту отдаётся уже готовый статус через свой эндпоинт или push.
Для маркетплейсов и магазинов с доставкой в API закладываю отдельный слой интеграции со службами вроде СДЭК: расчёт стоимости и сроков на этапе оформления заказа, а после - обновление статуса трека либо по расписанию, либо по вебхуку от службы, если она его поддерживает. Персональные данные покупателя - телефон, адрес - храню на серверах в РФ, это требование 152-ФЗ по локализации, и здесь не должно быть исключений ради удобства аналитики или сборки отчётов за границей.
Безопасность, лимиты нагрузки и мониторинг перед стартом
Перед релизом закладываю rate limiting на уровне API: для читающих эндпоинтов обычно 60 запросов в минуту на пользователя, для операций записи - в разы меньше, чтобы бот или сломанный клиент не положил базу лавиной запросов. HTTPS обязателен без исключений, включая внутренние вызовы между сервисами. На эндпоинты с деньгами добавляю подпись запроса на стороне сервера и сверку по времени, чтобы перехваченный запрос нельзя было повторить спустя час.
Логирование настраиваю так, чтобы у каждого запроса от мобильного клиента был свой correlation id - тогда жалобу пользователя «не проходит оплата» можно найти в логах за минуту, а не гадать по времени и user-агенту. Нагрузочное тестирование инструментом вроде k6 делаю до релиза в сторах, с симуляцией ожидаемого пика - если маркетинг планирует push-рассылку на всю базу в день запуска, бэкенд должен пережить не среднюю нагрузку, а именно этот всплеск. После запуска мониторинг и разбор инцидентов обычно веду в рамках техподдержки от 15 000 ₽ в месяц - это отдельная задача от разработки, и закладывать её в бюджет проекта стоит заранее, а не после первого падения на проде.
Частые вопросы
Сколько стоит разработка API для мобильного приложения
Зависит от числа сущностей и внешних интеграций, но как ориентир: бэкенд на Laravel с авторизацией, версионированием и базовым набором эндпоинтов я оцениваю от 100 000 ₽. Если добавляются платежи, доставка, push-инфраструктура и админ-панель, смета растёт и начинается уже от 300 000 ₽ как за полноценный веб-сервис со сроком от 8 недель.
Нужен ли отдельный бэкенд, если у меня уже есть сайт с API
Часто нет смысла поднимать второй сервер - можно расширить существующий API новыми эндпоинтами под мобильный клиент, если архитектура это позволяет. Но если сайт и приложение обслуживают разные сценарии использования, например сайт для десктопных заказов, а приложение для курьеров с офлайн-режимом, отдельный бэкенд или хотя бы отдельный слой версионирования обычно экономит нервы обеим командам.
Что делать со старыми версиями приложения после смены API
Держать старую версию эндпоинтов живой, пока в аналитике видна заметная доля пользователей на старой версии клиента - обычно это 6-9 месяцев после релиза новой версии API. Форсированное обновление через блокирующий экран стоит включать только при критичных изменениях, например в схеме оплаты, и предупреждать пользователей заранее.
Как быстро можно запустить бэкенд для MVP мобильного приложения
Минимальный набор - авторизация, основные CRUD-эндпоинты и push-уведомления - реально закрыть за 3-5 недель на Laravel, если контракт API согласован с мобильной командой заранее. Платежи, доставка и админ-панель обычно выносятся во вторую итерацию, чтобы не тормозить первый релиз в сторах.