Сітьовий шар мобільного додатку
Запрос йде, відповідь не приходить, timeout — 30 секунд. Користувач дивиться на спіннер. Сіті немає — мобільна карта в метро. Або сіть є, але сервер повернув 200 з HTML-сторінкою помилки замість JSON — і додаток падає при JSONDecoder.decode(). Сітьовий шар мобільного додатку повинен явно обробляти ці сценарії, а не покладатися на те, що «з'єднання завжди є».
REST та вибір клієнтської бібліотеки
Alamofire (iOS) — де-факто стандарт для Swift-проектів. Поверх URLSession додає request chaining, response validation, automatic retry, certificate pinning через ServerTrustManager. AF.request() з .validate() повертає помилку для будь-якого статус-коду поза 200–299. Без .validate() Alamofire вважає 404 та 500 успішними відповідями.
AF.request("https://api.example.com/orders")
.validate(statusCode: 200..<300)
.responseDecodable(of: OrdersResponse.self) { response in
switch response.result {
case .success(let orders): // ...
case .failure(let error): // завжди обробляємо
}
}
Зі Swift Concurrency — async-версія через serializingDecodable:
let response = try await AF.request(url)
.validate()
.serializingDecodable(OrdersResponse.self).value
Retrofit (Android) — аннотаційний HTTP-клієнт поверх OkHttp. Інтерфейс з аннотаціями компілюється в реалізацію. @GET, @POST, @Path, @Query, @Body — декларативне описання API. Converters (GsonConverterFactory, MoshiConverterFactory, KotlinxSerializationConverterFactory) десеріалізують відповідь автоматично.
OkHttp під капотом дає: connection pooling, transparent gzip, HTTP/2 multiplex. HttpLoggingInterceptor — логування запитів/відповідей в debug-збірці. Authenticator — автоматичне оновлення токена при 401.
Ktor (KMM/Flutter) — мультиплатформний HTTP-клієнт. На iOS працює через Darwin engine (URLSession), на Android — через OkHttp. Єдиний код для обох платформ при KMM-архітектурі.
GraphQL: коли REST створює проблеми
REST повертає фіксовану структуру. Екран профілю потребує name, avatar, email — сервер повертає 40 полів. Екран списку потребує тільки id та name — той же endpoint, ті ж 40 полів. Over-fetching.
GraphQL вирішує це: клієнт запитує ровно ті поля, які потребує. Це критично для мобільних, де трафік та час парсингу — реальні обмеження.
Apollo iOS та Apollo Kotlin — клієнти для GraphQL. Кодогенерація за схемою: schema.graphql + query-файли → типізовані Swift/Kotlin-класи. Немає строкових запитів, немає ручного парсингу — всё типобезпечно на етапі компіляції.
Subscriptions через WebSocket вбудовані в Apollo — real-time оновлення даних без polling.
Практичне обмеження: GraphQL складніше кешувати на рівні HTTP (один POST-endpoint). Apollo використовує нормалізований in-memory кеш з InMemoryNormalizedCache — запити з перетинаючимися даними оновлюють кеш без дублювання.
WebSocket: real-time без polling
Polling (setInterval кожні 5 секунд) — трата батареї та трафіку. WebSocket — постійне двунаправлене з'єднання.
iOS: URLSessionWebSocketTask (нативний, iOS 13+). Відправка через send(.string(message)), отримання через receive() в async loop.
Android: OkHttp WebSocket — newWebSocket() повертає WebSocket, WebSocketListener обробляє події: onOpen, onMessage, onClosing, onFailure.
Обов'язкова обробка reconnect: мобільна сіть нестабільна. При onFailure — експоненціальний backoff: 1с → 2с → 4с → 8с → максимум 60с. Без reconnect-логіки додаток теряє з'єднання в метро та не відновлює його.
Socket.IO — надбудова над WebSocket з автоматичним reconnect, room/namespace, fallback на long-polling. Зручна, якщо backend вже використовує Socket.IO. Для нових проектів краще нативний WebSocket — менше залежностей.
gRPC: для високонавантажених сервісів
gRPC з protobuf — бінарна серіалізація проти JSON: менший розмір, швидший парсинг. Для мобільних це ощутимо на слабких пристроях та повільній мережі.
grpc-swift для iOS, grpc-kotlin для Android. Protobuf-схема компілюється в типізовані класи на обох платформах. Streaming (server-side, client-side, bidirectional) — нативна можливість gRPC, не надбудова.
Практичний поріг застосування: gRPC обґрунтований при високій частоті запитів (trading, IoT, внутрішні мікросервіси) або коли latency критична. Для звичайного CRUD-API REST простіший у дебагу та моніторингу.
Offline-режим та кеширування
Мобільний додаток повинен працювати без мережі — хоча б у read-only режимі. Користувач теряє з'єднання, бачить раніше завантажені дані, а не екран помилки.
iOS: URLCache для HTTP-кеширування (поважає Cache-Control заголовки). Core Data або SwiftData для структурованих даних. NWPathMonitor — відслідковування доступності мережі.
Android: OkHttp Cache + CacheControl у запитах. Room для локального сховища. ConnectivityManager.NetworkCallback — моніторинг стану мережі.
Паттерн offline-first: при відкритті екрана спочатку показуємо дані з кешу, паралельно робимо сітьовий запит, оновлюємо UI при отриманні відповіді. Користувач бачить контент відразу, а не спіннер.
Certificate Pinning
Корпоративний proxy може перехопити HTTPS-з'єднання через підміну сертифіката. Certificate pinning це запобігає: додаток приймає тільки конкретний сертифікат або публічний ключ.
Alamofire: ServerTrustManager з PinnedCertificatesTrustEvaluator. OkHttp: CertificatePinner з SHA-256 хешем публічного ключа.
Операційна складність: при ротації сертифіката на сервері усі старі версії додатку перестають працювати. Рішення — pinning на публічний ключ CA, а не на leaf-сертифікат, або підтримка кількох пінів одночасно з grace period.
Терміни
Реалізація сітьового шару з REST, retry, кешуванням та offline-режимом — 1–2 тижні. Додання GraphQL або WebSocket — ще 1–2 тижні залежно від складності. gRPC з protobuf — 2–3 тижні включаючи генерацію коду та інтеграцію. Вартість розраховується індивідуально після аналізу вимог до API та offline-поведінки.







