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 по популярност, заемайки първо място сред HTTP клиентите в екосистемата на Flutter според данните на pub.dev.
Dio поддържа три адаптера: DartNativeAdapter (по подразбиране на Android, iOS, Desktop), BrowserAdapter (в Web) и IOAdapter. Адаптерът се избира автоматично в зависимост от платформата. Dio също така предоставя унифициран интерфейс за всички платформи на Flutter — Android, iOS, Web, macOS, Windows и Linux.
Архитектурата на Dio е изградена върху верига от обработващи елементи (handler chain). Всяка заявка преминава през последователност от прихващачи, които могат да модифицират заявката (InterceptorsWrapper.onRequest), отговора (onResponse) или да обработят грешката (onError). След прихващачите заявката достига до трансформаторите (Transformer), които преобразуват данните преди изпращане.
Инстанцията на Dio се конфигурира чрез обекта BaseOptions, който съдържа основния URL, подразбиращи се заглавия, времеви ограничения, тип отговор (JSON, stream, plain), параметри на заявката и формат на данните. Тези настройки се прилагат към всички заявки, но могат да бъдат презаписани в конкретна заявка. 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). В поточен режим Response.data връща ResponseBody, който може да се чете на части. Това е удобно за големи payload файлове, когато пълното зареждане в паметта не е желателно. Plain режим връща суров низ без автоматично разбор на JSON.
Прихващачите — ключов механизъм на Dio за прихващане и модификация на заявки, отговори и грешки. Те напълно заместват Interceptor от OkHttp и плъгините от Ktor, но с API специфично за Dart и поддръжка на асинхронност чрез Future. Прихващачите могат да се добавят както в глобалната конфигурация на Dio, така и за отделни заявки.
| Метод на прихващача | Предназначение | Пример за употреба |
|---|---|---|
| onRequest | Модификация на заявката преди изпращане | Добавяне на токен за авторизация |
| onResponse | Обработка на успешен отговор | Преобразуване на данни в DTO обекти |
| onError | Обработка на грешка при заявка | Автоматичен повторен опит при 503 |
Вграденият LogInterceptor регистрира всяка заявка: метод, URL, заглавия, тяло и време за изпълнение. Има два режима: compact (един ред на заявка) и full (пълна информация с тяло). LogInterceptor е особено полезен по време на разработка, но се препоръчва да се изключва в release версии чрез условен import или глобален флаг.
Персонализирани прихващачи се създават чрез класа InterceptorsWrapper. Може да се презапише един, два или и трите метода (onRequest, onResponse, onError). Dio изпълнява прихващачите стриктно в реда на добавянето им в списъка interceptors. Ако прихващач не извика handler.next(), веригата се прекъсва и отговорът/грешката не достигат до приложението.
За автентикация в Dio се използва прихващач, който добавя Bearer токен в заглавието Authorization. Ако сървърът върне 401, прихващачът в onError се опитва да обнови токена чрез refresh заявка и повтаря оригиналната заявка с новия токен. Този модел се нарича token refresh interceptor и се имплементира чрез DioException с проверка на response?.statusCode == 401.
Dio предоставя вградена поддръжка за логика за повторен опит чрез пакета dio_smart_retry или персонализиран RetryInterceptor. Повторният опит е важен за мобилни приложения: при загуба на връзка за 2–3 секунди Dio хвърля DioException с тип connectionTimeout или connectionError. RetryInterceptor прихваща това изключение и повтаря заявката до 3 пъти с експоненциално закъснение (1s, 2s, 4s), което повишава надеждността на приложението в условия на нестабилна мрежа.
Нека разгледаме основна 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 се активира преди изпращане, модифицирайки заглавията. При отговор 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. Много разработчици хващат само общия Exception, губейки информация за типа грешка и възможността за персонализираната ѝ обработка. Използвайте DioException.type за определяне на причината за повредата.
Пренебрегване на CancelToken води до изтичане на заявки. Ако потребителят напусне екрана, докато заявката все още се изпълнява, Dio консумира ресурси и може да се опита да актуализира унищожен State. Винаги създавайте CancelToken за всяка заявка и го отменяйте в dispose(). CancelToken генерира DioException с тип cancel, който трябва да се обработва правилно.
Липса на логика за повторен опит за временни повреди. На мобилни устройства мрежата често е временно недостъпна. Имплементирайте прихващач с автоматично повторение на заявката при времево ограничение или отговор 503/502. Използвайте RetryInterceptor от пакета dio_smart_retry или напишете персонализиран прихващач с експоненциално закъснение между опитите.
Често задавани въпроси
Dio предоставя прихващачи, глобална конфигурация на BaseOptions, FormData, напредък на качването и CancelToken. Http пакетът от екипа на Dart — минималистичен, без прихващачи и глобална конфигурация. 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 не управлява бисквитките автоматично. За поддръжка на бисквитки се използва пакетът dio_cookie_manager заедно с cookie_jar. CookieManager прихваща заглавните части Set-Cookie и Cookie и запазва бисквитките в PersistCookieJar за автоматично изпращане в следващи заявки към същия домейн.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също