Dio — este un client HTTP puternic pentru Dart și Flutter, creat de inginerul chinez Wenda Wang. Biblioteca oferă un API avansat cu suport pentru interceptoare, FormData, încărcarea fișierelor și anularea cererilor. Conform datelor pub.dev, 2025, Dio este cel mai popular client HTTP din ecosistemul Flutter, cu peste 8 mii de stele pe GitHub.
Principalele
Dio — este o bibliotecă puternică de client HTTP pentru limbajul Dart, cea mai utilizată în aplicațiile Flutter. Dio oferă un API bogat cu suport pentru interceptoare, configurare globală, transformatoare, FormData, încărcarea fișierelor și gestionarea flexibilă a timeout-urilor, ceea ce îl face alegerea principală pentru comunicațiile de rețea în comunitatea Flutter.
Biblioteca a fost creată de Wenda Wang în 2018 ca alternativă la dart:io HttpClient încorporat, care nu avea multe capacități moderne: configurare unificată pentru toate cererile, interceptoare și serializare automată. Până în 2025, Dio a depășit pachetul http de la echipa Dart în popularitate, ocupând locul întâi printre clienții HTTP din ecosistemul Flutter conform datelor pub.dev.
Dio suportă trei adaptoare: DartNativeAdapter (implicit pe Android, iOS, Desktop), BrowserAdapter (pe Web) și IOAdapter. Adaptorul este selectat automat în funcție de platformă. Dio oferă, de asemenea, o interfață unificată pentru toate platformele Flutter — Android, iOS, Web, macOS, Windows și Linux.
Arhitectura Dio este construită pe un lanț de handlere (handler chain). Fiecare cerere trece printr-o succesiune de interceptoare care pot modifica cererea (InterceptorsWrapper.onRequest), răspunsul (onResponse) sau pot gestiona eroarea (onError). După interceptoare, cererea ajunge la transformatoare (Transformer) care transformă datele înainte de trimitere.
Instanța Dio este configurată prin obiectul BaseOptions care conține URL-ul de bază, antetele implicite, timeout-urile, tipul răspunsului (JSON, stream, plain), parametrii de interogare și formatul datelor. Aceste setări se aplică tuturor cererilor, dar pot fi suprascrise într-o anumită cerere. BaseOptions asigură un punct unic de configurare pentru întreaga aplicație, simplificând schimbarea endpoint-ului API sau adăugarea de antete globale.
Fiecare cerere în Dio returnează Response<T>, unde T — este tipul datelor după procesarea de către transformatoare. În mod implicit, Dio transformă automat răspunsul JSON în Map<String, dynamic>. Pentru răspunsuri tipizate se utilizează Dio împreună cu pachetele de serializare: json_serializable, freezed sau built_value. Response conține data, headers, statusCode, requestOptions și date suplimentare.
Configurarea de bază se creează prin Dio(BaseOptions). Se poate seta baseUrl pentru toate cererile, connectTimeout și receiveTimeout, antetele content-type și accept, precum și queryParameters. Toți acești parametri se aplică fiecărei cereri, eliminând duplicarea codului și centralizând gestionarea setărilor de rețea.
Dio suportă două moduri de serializare: implicit JSON (responseType: ResponseType.json) și flux (ResponseType.stream). În modul flux, Response.data returnează un ResponseBody care poate fi citit pe părți. Acest lucru este convenabil pentru fișierele payload mari, când încărcarea completă în memorie nu este dorită. Modul plain returnează un șir brut fără parsare automată JSON.
Interceptoarele — mecanismul cheie al Dio pentru interceptarea și modificarea cererilor, răspunsurilor și erorilor. Ele înlocuiesc complet Interceptor din OkHttp și pluginurile din Ktor, dar cu API specific Dart și suport pentru asincronism prin Future. Interceptoarele pot fi adăugate atât în configurarea globală a Dio, cât și pentru cereri individuale.
| Metoda interceptoare | Destinație | Exemplu de utilizare |
|---|---|---|
| onRequest | Modificarea cererii înainte de trimitere | Adăugarea token-ului de autorizare |
| onResponse | Procesarea răspunsului de succes | Transformarea datelor în obiecte DTO |
| onError | Gestionarea erorii cererii | Reîncercare automată la 503 |
Încorporatul LogInterceptor înregistrează fiecare cerere: metoda, URL, antete, corpul și timpul de execuție. Are două moduri: compact (o linie per cerere) și full (informații complete cu corpul). LogInterceptor este util în special în timpul dezvoltării, dar se recomandă dezactivarea lui în versiunile release prin import condiționat sau un flag global.
Interceptoarele personalizate se creează prin clasa InterceptorsWrapper. Se pot suprascrie una, două sau toate cele trei metode (onRequest, onResponse, onError). Dio execută interceptoarele strict în ordinea adăugării lor în lista interceptors. Dacă un intercepttor nu apelează handler.next(), lanțul se întrerupe, iar răspunsul/eroarea nu ajung la aplicație.
Pentru autentificare în Dio se folosește un intercepttor care adaugă token-ul Bearer în antetul Authorization. Dacă serverul returnează 401, intercepttorul în onError încearcă să reîmprospăteze token-ul printr-o cerere refresh și repetă cererea originală cu noul token. Acest model se numește token refresh interceptor și se implementează prin DioException cu verificarea response?.statusCode == 401.
Dio oferă suport încorporat pentru logica de reîncercare prin pachetul dio_smart_retry sau un RetryInterceptor personalizat. Reîncercarea este importantă pentru aplicațiile mobile: la pierderea conexiunii pentru 2–3 secunde, Dio aruncă DioException cu tipul connectionTimeout sau connectionError. RetryInterceptor interceptează această excepție și repetă cererea de până la 3 ori cu întârziere exponențială (1s, 2s, 4s), ceea ce crește fiabilitatea aplicației în condiții de rețea instabilă.
Să analizăm cererea GET de bază prin Dio. Se creează o instanță cu BaseOptions, se setează URL-ul de bază și timeout-urile. Cererea se execută prin metoda get(), care returnează Response cu datele în format 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['autentificare'])
Pentru cererea POST cu corp JSON se transmite un obiect Map sau un DTO personalizat. Dio serializează automat Map-ul în JSON prin jsonEncode. Pentru DTO tipizat se utilizează opțiunea queryParameters, câmpul data sau un Transformer personalizat.
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'])
Intercepttorul personalizat adaugă token-ul Bearer la fiecare cerere. Metoda onRequest acționează înainte de trimitere, modificând antetele. La răspunsul 401, intercepttorul poate reîmprospăta token-ul și repeta cererea prin metoda 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 simplifică încărcarea fișierelor prin FormData. Pentru a trimite un fișier se creează un MultipartFile din File, Bytes sau AssetBundle. FormData setează automat antetul multipart/form-data cu granița și codarea corectă. Dio suportă progresul încărcării prin onSendProgress.
Pentru descărcarea fișierelor se folosește metoda download(), care salvează fluxul de date direct în fișier. Dio suportă reluarea (resume) descărcărilor întrerupte prin antetul Range, ceea ce este util în special pentru fișierele mari. Progresul descărcării este urmărit prin onReceiveProgress, permițând afișarea unei bare de progres în UI.
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('Încărcare: $progress%')
},
)
// Descărcare fișier
await dio.download(
'https://example.com/file.zip',
'/storage/emulated/0/Download/file.zip',
onReceiveProgress: (received, total) {
print('Descărcare: ${received / total * 100}%')
},
)
Gestionarea incorectă a erorilor — cea mai frecventă problemă. Dio aruncă DioException (fost DioError) la orice problemă: lipsa rețelei, timeout, erori HTTP 4xx/5xx. Mulți dezvoltatori prind doar Exception generic, pierzând informația despre tipul erorii și posibilitatea gestionării personalizate. Folosiți DioException.type pentru a determina cauza defecțiunii.
Ignorarea CancelToken duce la scurgeri de cereri. Dacă utilizatorul părăsește ecranul, iar cererea continuă să se execute, Dio consumă resurse și poate încerca să actualizeze un State distrus. Creați întotdeauna un CancelToken pentru fiecare cerere și anulați-l în dispose(). CancelToken generează DioException cu tipul cancel, care trebuie gestionat corect.
Lipsa logicii de reîncercare pentru defecțiuni temporare. Pe dispozitivele mobile, rețeaua este adesea indisponibilă temporar. Implementați un intercepttor cu reîncercare automată a cererii la timeout sau răspuns 503/502. Utilizați RetryInterceptor din pachetul dio_smart_retry sau scrieți un intercepttor personalizat cu întârziere exponențială între încercări.
Întrebări frecvente
Dio oferă interceptoare, configurare globală BaseOptions, FormData, progresul încărcării și CancelToken. Pachetul http de la echipa Dart — minimalist, fără interceptoare și configurare globală. Dio este utilizat în proiecte mari, http — pentru scripturi simple.
Dio transformă în mod implicit JSON în Map prin jsonDecode. Pentru serializare tipizată utilizați pachetele json_serializable sau freezed. Creați un intercepttor personalizat care în onResponse transformă response.data în DTO prin fromJson().
Creați un CancelToken și transmiteți-l în opțiunile cererii. Apelul token.cancel() întrerupe cererea și provoacă DioException cu tipul cancel. CancelToken suportă anularea mai multor cereri simultan, ceea ce este convenabil pentru anularea tuturor cererilor la părăsirea ecranului.
Da, Dio funcționează pe toate cele șase platforme Flutter: Android, iOS, Web, macOS, Windows și Linux. Pentru fiecare platformă se utilizează un client HTTP adaptiv: DartNativeAdapter (platforme native) și BrowserAdapter (Web). API unificat pentru toate platformele — avantajul cheie al Dio în proiectele Flutter.
Dio nu gestionează cookie-urile automat. Pentru suportul cookie-urilor se utilizează pachetul dio_cookie_manager împreună cu cookie_jar. CookieManager interceptează antetele Set-Cookie și Cookie și salvează cookie-urile în PersistCookieJar pentru trimiterea automată în cererile ulterioare către același domeniu.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și