Dio — це потужний HTTP-клієнт для Dart та Flutter, розроблений китайським інженером Вендою Вангом. Бібліотека надає розширений API з підтримкою перехоплювачів, FormData, завантаження файлів та скасування запитів. За даними pub.dev, 2025, Dio є найпопулярнішим HTTP-клієнтом в екосистемі Flutter з понад 8 тисячами зірок на GitHub.
Головне
Dio — це потужна HTTP-клієнтська бібліотека для мови Dart, найбільш широко використовувана в додатках на Flutter. Dio надає багатий API з підтримкою перехоплювачів, глобальної конфігурації, трансформерів, FormData, завантаження файлів та гнучкого керування таймаутами, що робить його основним вибором для мережевої взаємодії в спільноті Flutter.
Бібліотека була створена Вендою Вангом у 2018 році як альтернатива вбудованому dart:io HttpClient, який не мав багатьох сучасних можливостей: єдиної конфігурації для всіх запитів, перехоплювачів та автоматичної серіалізації. До 2025 року Dio обігнав за популярністю http-пакет від Dart team, посівши перше місце серед HTTP-клієнтів в екосистемі Flutter за даними pub.dev.
Dio підтримує три адаптери: DartNativeAdapter (за замовчуванням на Android, iOS, Desktop), BrowserAdapter (на Web) та IOAdapter. Адаптер автоматично вибирається залежно від платформи. Dio також надає єдиний інтерфейс для всіх платформ Flutter — Android, iOS, Web, macOS, Windows та Linux.
Архітектура Dio побудована на ланцюжку обробників. Кожен запит проходить через послідовність перехоплювачів, які можуть модифікувати запит (InterceptorsWrapper.onRequest), відповідь (onResponse) або обробити помилку (onError). Після перехоплювачів запит потрапляє в трансформери (Transformer), які перетворюють дані перед відправкою.
Екземпляр Dio налаштовується через об'єкт BaseOptions, що містить базовий URL, заголовки за замовчуванням, таймаути, тип відповіді (JSON, stream, plain), query-параметри та формат даних. Ці налаштування застосовуються до всіх запитів, але можуть бути перевизначені в конкретному запиті. BaseOptions забезпечує єдину точку конфігурації для всього додатка, що спрощує зміну API-ендпоінта або додавання глобальних заголовків.
Кожен запит у Dio повертає Response<T>, де T — тип даних після обробки трансформерами. За замовчуванням Dio автоматично перетворює JSON-відповідь у Map<String, dynamic>. Для типізованих відповідей використовується Dio разом із пакетами серіалізації: json_serializable, freezed або built_value. Response містить data, headers, statusCode, requestOptions та додаткові дані.
Базова конфігурація створюється через Dio(BaseOptions). Можна задати baseUrl для всіх запитів, connectTimeout та receiveTimeout, заголовки content-type та accept, а також queryParameters. Всі ці параметри застосовуються до кожного запиту, що усуває дублювання коду та централізує керування мережевими налаштуваннями.
Dio підтримує два режими серіалізації: за замовчуванням JSON (responseType: ResponseType.json) та потоковий (ResponseType.stream). У режимі stream Response.data повертає ResponseBody, який можна читати частинами. Це зручно для великих файлів, коли повне завантаження в пам'ять небажане. Режим plain повертає сирий рядок без автоматичного парсингу JSON.
Перехоплювачі — ключовий механізм Dio для перехоплення та модифікації запитів, відповідей та помилок. Вони повністю замінюють Interceptor з OkHttp та плагіни з Ktor, але з Dart-специфічним API та підтримкою асинхронності через Future. Перехоплювачі можна додавати як у глобальній конфігурації Dio, так і для окремих запитів.
| Метод перехоплювача | Призначення | Приклад використання |
|---|---|---|
| onRequest | Модифікація запиту перед відправкою | Додавання токена авторизації |
| onResponse | Обробка успішної відповіді | Перетворення data в DTO-об'єкти |
| onError | Обробка помилки запиту | Автоматичний retry при 503 |
Вбудований LogInterceptor логує кожен запит: метод, URL, заголовки, тіло та час виконання. Він має два режими: compact (один рядок на запит) та full (повна інформація з тілом). LogInterceptor особливо корисний при розробці, але його рекомендується вимикати в релізних збірках через умовний import або глобальний прапорець.
Кастомні перехоплювачі створюються через клас InterceptorsWrapper. Можна перевизначити один, два або всі три методи (onRequest, onResponse, onError). Dio виконує перехоплювачі строго в порядку їх додавання до списку interceptors. Якщо перехоплювач не викликає handler.next(), ланцюжок переривається, і відповідь/помилка не доходять до додатка.
Для аутентифікації в Dio використовується перехоплювач, який додає Bearer-токен у заголовок Authorization. Якщо сервер повертає 401, перехоплювач у onError намагається оновити токен через refresh-запит і повторює оригінальний запит з новим токеном. Цей патерн називається token refresh interceptor і реалізується через DioException з перевіркою response?.statusCode == 401.
Dio надає вбудовану підтримку retry-логіки через пакет dio_smart_retry або кастомний RetryInterceptor. Ретрай важливий для мобільних додатків: при втраті з'єднання на 2-3 секунди Dio викидає DioException з типом connectionTimeout або connectionError. RetryInterceptor перехоплює це виключення та повторює запит до 3 разів з експоненційною затримкою (1с, 2с, 4с), що підвищує надійність додатка в умовах нестабільної мережі.
Розглянемо базовий GET-запит через Dio. Створюється екземпляр з BaseOptions, задається базовий URL та таймаути. Запит виконується через метод get(), який повертає Response з даними у форматі Map.
final dio = Dio(BaseOptions(
baseUrl: 'https://api.github.com',
connectTimeout: Duration(seconds: 15),
receiveTimeout: Duration(seconds: 15),
headers: {
'Accept': 'application/vnd.github.v3+json',
},
))
final response = await dio.get('/users/octocat')
print(response.data['логін'])
Для POST-запиту з JSON-тілом передається об'єкт Map або кастомний DTO. Dio автоматично серіалізує Map у JSON через jsonEncode. Для типізованих DTO використовується опція queryParameters, data-поле або кастомний Transformer.
final data = {
'name': 'my-project',
'description': 'Created via Dio',
'private': false,
}
final response = await dio.post(
'/user/repos',
data: data,
options: Options(
contentType: ContentType.json.value,
),
)
print(response.data['id'])
Кастомний перехоплювач додає Bearer-токен до кожного запиту. Метод onRequest спрацьовує до відправки, модифікуючи headers. При відповіді 401 перехоплювач може оновити токен і повторити запит через метод dio.fetch(requestOptions).
class AuthInterceptor extends InterceptorsWrapper {
final String token
AuthInterceptor(this.token)
@override
void onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) {
options.headers['Authorization'] = 'Bearer $token'
handler.next(options)
}
}
dio.interceptors.add(AuthInterceptor('ghp_abc123'))
Dio спрощує завантаження файлів через FormData. Для відправки файлу створюється MultipartFile з File, Bytes або AssetBundle. FormData автоматично встановлює заголовок multipart/form-data з правильною межею та кодуванням. Dio підтримує прогрес завантаження через onSendProgress.
Для вивантаження файлів використовується метод download(), який зберігає потік даних безпосередньо у файл. Dio підтримує докачку (resume) при перерваних завантаженнях через заголовок Range, що особливо корисно для великих файлів. Прогрес вивантаження відстежується через onReceiveProgress, дозволяючи відображати смугу завантаження в інтерфейсі.
final formData = FormData.fromMap({
'file': await MultipartFile.fromFile(
'/path/to/photo.jpg',
filename: 'photo.jpg',
),
'description': 'Profile photo',
})
await dio.post(
'/upload',
data: formData,
onSendProgress: (sent, total) {
final progress = sent / total * 100
print('Вивантаження: $progress%')
},
)
// Завантаження файлу
await dio.download(
'https://example.com/file.zip',
'/storage/emulated/0/Download/file.zip',
onReceiveProgress: (received, total) {
print('Завантаження: ${received / total * 100}%')
},
)
Неправильна обробка помилок — найчастіша проблема. Dio викидає DioException (раніше DioError) при будь-яких проблемах: відсутність мережі, таймаут, HTTP-помилки 4xx/5xx. Багато розробників ловлять лише generic Exception, втрачаючи інформацію про тип помилки та можливості її кастомної обробки. Використовуйте DioException.type для визначення причини збою.
Ігнорування CancelToken призводить до витоку запитів. Якщо користувач пішов з екрана, а запит продовжує виконуватися, Dio витрачає ресурси та може спробувати оновити знищений State. Завжди створюйте CancelToken для кожного запиту та скасовуйте його в dispose(). CancelToken генерує DioException з типом cancel, який потрібно правильно обробляти.
Відсутність retry-логіки для тимчасових збоїв. На мобільних пристроях мережа часто недоступна короткочасно. Реалізуйте перехоплювач з автоматичним повторенням запиту при таймауті або відповіді 503/502. Використовуйте RetryInterceptor з пакета dio_smart_retry або напишіть кастомний перехоплювач з експоненційною затримкою між спробами.
Часті запитання
Dio надає перехоплювачі, глобальну конфігурацію BaseOptions, FormData, прогрес завантаження та CancelToken. Http-пакет від Dart team — мінімалістичний, без перехоплювачів та глобальної конфігурації. Dio використовують у великих проектах, http — для простих скриптів.
Dio за замовчуванням перетворює JSON у Map через jsonDecode. Для типізованої серіалізації використовуйте пакети json_serializable або freezed. Створіть кастомний перехоплювач, який в onResponse перетворює response.data в DTO через fromJson().
Створіть CancelToken та передайте його в опції запиту. Виклик token.cancel() перериває запит і викликає DioException з типом cancel. CancelToken підтримує скасування кількох запитів одночасно, що зручно для скасування всіх запитів при виході з екрана.
Так, Dio працює на всіх шести платформах Flutter: Android, iOS, Web, macOS, Windows та Linux. Для кожної платформи використовується адаптивний HTTP-клієнт: DartNativeAdapter (нативні платформи) та BrowserAdapter (Web). Єдиний API для всіх платформ — ключова перевага Dio в проектах Flutter.
Dio не керує cookie автоматично. Для підтримки cookie використовується пакет dio_cookie_manager спільно з cookie_jar. CookieManager перехоплює Set-Cookie та Cookie заголовки та зберігає куки в PersistCookieJar для автоматичної відправки в наступних запитах до того ж домену.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.