Мобильное приложение дёргает сервер десятки раз в день, но ответ приходит с задержкой в 2-3 секунды из-за неоптимального API. Трафик растёт, пользователи жалуются на «вечные» списки. Типичная ситуация — API, спроектированное для веба, перенесли на мобильный клиент без адаптации. В результате UX страдает, а счёт за облачные ресурсы увеличивается на 30-50%. Мы проектируем REST API для мобильных приложений с учётом специфики: нестабильное соединение, ограниченный трафик, многоверсионность. В App Store живут пользователи с версиями двухлетней давности — это влияет на архитектурные решения с первого дня. Грамотное API — залог быстрого UX и экономии трафика в 2-3 раза.
Как спроектировать эндпоинты для мобильного клиента?
Классическая ошибка — эндпоинты, возвращающие слишком много данных. Экран профиля не должен тянуть весь объект пользователя с вложенными связями, если нужны только аватар и имя. BFF (Backend for Frontend) паттерн решает это: отдельный слой API, оптимизированный под мобильные экраны. Альтернатива — fields параметр в запросе (?fields=id,name,avatar).
Почему cursor-based пагинация лучше offset?
Offset-based пагинация (?page=2&limit=20) не подходит для feeds в реальном времени — при добавлении новых записей смещение съезжает, пользователь видит дубли. Cursor-based (?after=eyJpZCI6MTIzfQ==) лишена этой проблемы: курсор фиксирует позицию, и новые записи не нарушают порядок. По нашим данным, после перехода на cursor-based время загрузки ленты сокращается на 40%, а расход трафика падает на 25%. Обязательно возвращайте hasMore флаг и nextCursor в ответе.
Версионирование API
Начинайте с версии в URL (/api/v1/). Мобильное приложение не обновляется принудительно — 15-20% пользователей остаются на старых версиях месяцами. v1 должна жить параллельно с v2 минимум 6-12 месяцев. Игнорирование этого правила приводит к падению приложения после изменений, что мы не раз видели на практике.
Сетевой слой на клиенте
Android (Kotlin): Retrofit 2 + OkHttp + Kotlin Coroutines — устоявшийся стек. Interceptor в OkHttp для добавления Authorization заголовка, логирования (только в debug) и retry-логики:
class AuthInterceptor(private val tokenProvider: TokenProvider) : Interceptor { override fun intercept(chain: Chain): Response { val request = chain.request().newBuilder() .addHeader("Authorization", "Bearer ${tokenProvider.getToken()}") .build() val response = chain.proceed(request) if (response.code == 401) { tokenProvider.refresh() // retry с новым токеном } return response } } iOS (Swift): URLSession нативно или Alamofire. Для типобезопасных запросов — Codable модели. RequestInterceptor в Alamofire для автоматического refresh токена аналогичен OkHttp Interceptor.
Flutter: dio пакет с Interceptor — логика та же. retrofit_dart генерирует типобезопасный клиент из аннотаций по аналогии с Retrofit.
Обработка ошибок
Структурированные коды ошибок важнее HTTP-статусов для клиентской логики:
{ "error": { "code": "USER_NOT_FOUND", "message": "User with specified ID does not exist", "field": null } } code — машиночитаемый, клиент делает switch по нему. message — для разработчика, не для пользователя. Клиент показывает свои локализованные строки по code, а не сырое message из API. Валидационные ошибки должны возвращать field — название поля, которое не прошло проверку. Это позволяет подсвечивать конкретное поле в форме.
| Код ошибки | HTTP статус | Описание |
|---|---|---|
| USER_NOT_FOUND | 404 | Пользователь не найден |
| VALIDATION_ERROR | 422 | Ошибка валидации полей |
| TOKEN_EXPIRED | 401 | Истёк токен доступа |
Кеширование и оффлайн
HTTP-кеширование через Cache-Control и ETag снижает нагрузку на сервер на 30-50% и ускоряет UX. OkHttp поддерживает HTTP-кеш из коробки с указанием директории и размера. Но для оффлайн-работы нужен отдельный слой: Room (Android) или CoreData/SwiftData (iOS) как локальная копия данных. Repository паттерн разделяет источники данных.
| Механизм | Где применить | Выгода |
|---|---|---|
| HTTP-кеш | Статические данные (изображения, списки) | Снижение трафика на 30-50% |
| Локальная БД | Оффлайн-режим, кэш профиля | Работа без интернета |
Безопасность
- Certificate Pinning:
OkHttp.CertificatePinnerна Android,URLSessionDelegateсdidReceive challengeна iOS. Усложняет MITM-атаки, но требует плана ротации сертификатов. Согласно REST API best practices, это обязательный элемент защиты. - Не хранить JWT в
SharedPreferences(Android) илиUserDefaults(iOS). ИспользуйтеEncryptedSharedPreferences/Keychain. - HTTPS везде, без исключений. Никаких
cleartextв production.
Дополнительные меры безопасности:
- OAuth 2.0 с рефреш-токенами для долгоживущих сессий.
- Rate limiting на стороне сервера для предотвращения брутфорса.
- Audit лог всех запросов для отслеживания подозрительной активности.
Что входит в работу
Проектируем эндпоинты с учётом мобильной специфики, реализуем клиентский сетевой слой с interceptors, обработкой ошибок и retry, настраиваем кеширование и документацию через OpenAPI/Swagger. В результате вы получаете стабильное API, которое снижает затраты на трафик и ускоряет разработку клиентской части.
Срок: 5-12 дней в зависимости от количества эндпоинтов и необходимости бэкенда. Мы — команда с 8-летним опытом разработки мобильных API, реализовали 30+ проектов для iOS и Android. Закажите разработку API под ключ — получите оптимизированный бэкенд и клиентский сетевой слой за указанные сроки. Свяжитесь с нами для консультации.







