Dio: co to jest, funkcje klienta HTTP dla Flutter

Autor: IT Sectr Opublikowano: 2026-03-07 Czas czytania: 8 min

Dio — to potężny klient HTTP dla Dart i Flutter, stworzony przez chińskiego inżyniera Wenda Wanga. Biblioteka oferuje zaawansowane API z obsługą przechwytywaczy, FormData, przesyłania plików i anulowania żądań. Według danych pub.dev, 2025, Dio jest najpopularniejszym klientem HTTP w ekosystemie Flutter z ponad 8 tysiącami gwiazdek na GitHub.

Najważniejsze

  • Dio — potężny klient HTTP dla Dart i Flutter z przechwytywaczami i transformatorami
  • Interceptory — mechanizm przechwytywania żądań, odpowiedzi i błędów do logowania i autoryzacji
  • FormData — wbudowana obsługa multipart/form-data do przesyłania plików
  • Anulowanie żądań — CancelToken pozwala przerywać wykonywane żądania w dowolnym momencie
  • Transformery — niestandardowe przekształcanie danych przed wysłaniem i po otrzymaniu

Co to jest Dio?

Dio — to potężna biblioteka klienta HTTP dla języka Dart, najszerzej używana w aplikacjach Flutter. Dio zapewnia bogate API z obsługą przechwytywaczy, globalnej konfiguracji, transformatorów, FormData, przesyłania plików i elastycznego zarządzania limitami czasu, co czyni go głównym wyborem do komunikacji sieciowej w społeczności Flutter.

Biblioteka została stworzona przez Wenda Wanga w 2018 roku jako alternatywa dla wbudowanego dart:io HttpClient, który nie miał wielu nowoczesnych możliwości: jednolitej konfiguracji dla wszystkich żądań, przechwytywaczy i automatycznej serializacji. Do 2025 roku Dio wyprzedził pod względem popularności pakiet http od zespołu Dart, zajmując pierwsze miejsce wśród klientów HTTP w ekosystemie Flutter według danych pub.dev.

Dio obsługuje trzy adaptery: DartNativeAdapter (domyślnie na Android, iOS, Desktop), BrowserAdapter (w Web) i IOAdapter. Adapter jest automatycznie wybierany w zależności od platformy. Dio zapewnia również jednolity interfejs dla wszystkich platform Flutter — Android, iOS, Web, macOS, Windows i Linux.

Jak działa Dio

Architektura Dio jest zbudowana na łańcuchu handlerów (handler chain). Każde żądanie przechodzi przez sekwencję interceptory, które mogą modyfikować żądanie (InterceptorsWrapper.onRequest), odpowiedź (onResponse) lub obsłużyć błąd (onError). Po interceptorach żądanie trafia do transformerów (Transformer), które przekształcają dane przed wysłaniem.

Instancja Dio jest konfigurowana przez obiekt BaseOptions zawierający podstawowy URL, domyślne nagłówki, limity czasu, typ odpowiedzi (JSON, stream, plain), parametry zapytania i format danych. Te ustawienia są stosowane do wszystkich żądań, ale mogą zostać nadpisane w konkretnym żądaniu. BaseOptions zapewnia jednolity punkt konfiguracji dla całej aplikacji, co upraszcza zmianę endpointu API lub dodawanie globalnych nagłówków.

Każde żądanie w Dio zwraca Response<T>, gdzie T — typ danych po przetworzeniu przez transformery. Domyślnie Dio automatycznie przekształca odpowiedź JSON na Map<String, dynamic>. Dla typowanych odpowiedzi używa się Dio wraz z pakietami serializacji: json_serializable, freezed lub built_value. Response zawiera data, headers, statusCode, requestOptions i dane dodatkowe.

Globalna konfiguracja Dio

Podstawowa konfiguracja jest tworzona przez Dio(BaseOptions). Można ustawić baseUrl dla wszystkich żądań, connectTimeout i receiveTimeout, nagłówki content-type i accept, a także queryParameters. Wszystkie te parametry są stosowane do każdego żądania, co eliminuje powielanie kodu i centralizuje zarządzanie ustawieniami sieciowymi.

Dio obsługuje dwa tryby serializacji: domyślny JSON (responseType: ResponseType.json) i strumieniowy (ResponseType.stream). W trybie stream Response.data zwraca ResponseBody, który można czytać częściami. Jest to wygodne w przypadku dużych plików payload, gdy pełne załadowanie do pamięci jest niepożądane. Tryb plain zwraca surowy ciąg znaków bez automatycznego parsowania JSON.

Interceptory Dio

Interceptory — kluczowy mechanizm Dio do przechwytywania i modyfikacji żądań, odpowiedzi i błędów. Całkowicie zastępują one Interceptor z OkHttp i wtyczki z Ktor, ale z API specyficznym dla Dart i obsługą asynchroniczności przez Future. Interceptory można dodawać zarówno w globalnej konfiguracji Dio, jak i dla poszczególnych żądań.

Metoda interceptoraPrzeznaczeniePrzykład użycia
onRequestModyfikacja żądania przed wysłaniemDodawanie tokena autoryzacji
onResponseObsługa udanej odpowiedziPrzekształcanie data na obiekty DTO
onErrorObsługa błędu żądaniaAutomatyczne ponawianie przy 503

LogInterceptor

Wbudowany LogInterceptor loguje każde żądanie: metodę, URL, nagłówki, treść i czas wykonania. Ma dwa tryby: compact (jedna linia na żądanie) i full (pełna informacja z treścią). LogInterceptor jest szczególnie przydatny podczas programowania, ale zaleca się wyłączanie go w wersjach release poprzez warunkowy import lub globalną flagę.

Niestandardowe interceptory tworzy się przez klasę InterceptorsWrapper. Można nadpisać jeden, dwa lub wszystkie trzy metody (onRequest, onResponse, onError). Dio wykonuje interceptory ściśle w kolejności ich dodawania do listy interceptors. Jeśli interceptator nie wywoła handler.next(), łańcuch zostaje przerwany, a odpowiedź/błąd nie dociera do aplikacji.

Do autoryzacji w Dio używa się interceptora dodającego token Bearer do nagłówka Authorization. Jeśli serwer zwróci 401, interceptor w onError próbuje odświeżyć token przez żądanie refresh i powtarza oryginalne żądanie z nowym tokenem. Ten wzorzec nazywa się token refresh interceptor i jest implementowany przez DioException ze sprawdzeniem response?.statusCode == 401.

Dio zapewnia wbudowaną obsługę logiki ponawiania poprzez pakiet dio_smart_retry lub niestandardowy RetryInterceptor. Ponawianie jest ważne dla aplikacji mobilnych: przy utracie połączenia na 2–3 sekundy Dio rzuca DioException z typem connectionTimeout lub connectionError. RetryInterceptor przechwytuje ten wyjątek i powtarza żądanie do 3 razy z opóźnieniem wykładniczym (1s, 2s, 4s), co zwiększa niezawodność aplikacji w warunkach niestabilnej sieci.

Przykłady kodu Dio w Dart

Rozważmy podstawowe żądanie GET przez Dio. Tworzy się instancję z BaseOptions, ustawia podstawowy URL i limity czasu. Żądanie jest wykonywane przez metodę get(), zwracającą Response z danymi w formacie Map.

dart
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['zaloguj'])

Dla żądania POST z treścią JSON przekazuje się obiekt Map lub niestandardowy DTO. Dio automatycznie serializuje Map do JSON przez jsonEncode. Dla typowanych DTO używa się opcji queryParameters, pola data lub niestandardowego Transformera.

dart
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'])

Dodawanie interceptora autoryzacji

Niestandardowy interceptor dodaje token Bearer do każdego żądania. Metoda onRequest działa przed wysłaniem, modyfikując nagłówki. Przy odpowiedzi 401 interceptor może odświeżyć token i powtórzyć żądanie przez metodę dio.fetch(requestOptions).

dart
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'))

Przesyłanie i pobieranie plików przez Dio

Dio upraszcza przesyłanie plików przez FormData. Do wysłania pliku tworzy się MultipartFile z File, Bytes lub AssetBundle. FormData automatycznie ustawia nagłówek multipart/form-data z prawidłową granicą i kodowaniem. Dio obsługuje postęp przesyłania przez onSendProgress.

Do pobierania plików używa się metody download(), która zapisuje strumień danych bezpośrednio do pliku. Dio obsługuje dokańczanie (resume) przerwanych pobierań poprzez nagłówek Range, co jest szczególnie przydatne w przypadku dużych plików. Postęp pobierania jest śledzony przez onReceiveProgress, umożliwiając wyświetlanie paska postępu w interfejsie.

dart
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('Przesyłanie: $progress%')
    },
)

// Pobieranie pliku
await dio.download(
    'https://example.com/file.zip',
    '/storage/emulated/0/Download/file.zip',
    onReceiveProgress: (received, total) {
        print('Pobieranie: ${received / total * 100}%')
    },
)

Typowe błędy podczas pracy z Dio

Nieprawidłowa obsługa błędów — najczęstszy problem. Dio rzuca DioException (wcześniej DioError) przy wszelkich problemach: brak sieci, limit czasu, błędy HTTP 4xx/5xx. Wielu programistłow łapie tylko ogólny Exception, tracąc informację o typie błędu i możliwości jego niestandardowej obsługi. Używaj DioException.type do określenia przyczyny awarii.

Ignorowanie CancelToken prowadzi do wycieków żądań. Jeśli użytkownik opuści ekran, a żądanie nadal jest wykonywane, Dio zużywa zasoby i może próbować zaktualizować zniszczony State. Zawsze twórz CancelToken dla każdego żądania i anuluj go w dispose(). CancelToken generuje DioException z typem cancel, który należy poprawnie obsłużyć.

Brak logiki ponawiania dla tymczasowych awarii. Na urządzeniach mobilnych sieć jest często krótkotrwale niedostępna. Zaimplementuj interceptor z automatycznym ponawianiem żądania przy przekroczeniu limitu czasu lub odpowiedzi 503/502. Użyj RetryInterceptor z pakietu dio_smart_retry lub napisz niestandardowy interceptor z opóźnieniem wykładniczym między próbami.

Często zadawane pytania

Czym różni się Dio od pakietu http Dart?

Dio zapewnia interceptory, globalną konfigurację BaseOptions, FormData, postęp przesyłania i CancelToken. Pakiet http od zespołu Dart — minimalistyczny, bez przechwytywaczy i globalnej konfiguracji. Dio jest używany w dużych projektach, http — w prostych skryptach.

Jak serializować JSON w Dio?

Dio domyślnie przekształca JSON na Map przez jsonDecode. Do typowanej serializacji używaj pakietów json_serializable lub freezed. Utwórz niestandardowy interceptor, który w onResponse przekształca response.data na DTO przez fromJson().

Jak anulować żądanie w Dio?

Utwórz CancelToken i przekazać go w opcjach żądania. Wywołanie token.cancel() przerywa żądanie i powoduje DioException z typem cancel. CancelToken obsługuje anulowanie kilku żądań jednocześnie, co jest wygodne do anulowania wszystkich żądań przy opuszczaniu ekranu.

Czy Dio działa na wszystkich platformach Flutter?

Tak, Dio działa na wszystkich sześciu platformach Flutter: Android, iOS, Web, macOS, Windows i Linux. Dla każdej platformy używany jest adaptacyjny klient HTTP: DartNativeAdapter (platformy natywne) i BrowserAdapter (Web). Jednolity API dla wszystkich platform — kluczowa zaleta Dio w projektach Flutter.

Jak Dio obsługuje cookie?

Dio nie zarządza cookie automatycznie. Do obsługi cookie używa się pakietu dio_cookie_manager wraz z cookie_jar. CookieManager przechwytuje nagłówki Set-Cookie i Cookie oraz zapisuje ciasteczka w PersistCookieJar do automatycznego wysyłania w kolejnych żądaniach do tej samej domeny.

Podsumowanie

  • Dio — najpopularniejszy klient HTTP w Flutter z przechwytywaczami i transformatorami
  • Interceptory onRequest, onResponse i onError modyfikują żądania i odpowiedzi
  • FormData i MultipartFile upraszczają przesyłanie plików na serwer
  • CancelToken poprawnie anuluje żądania, aby zapobiec wyciekom pamięci
  • BaseOptions centralizuje konfigurację URL, nagłówków i limitów czasu
  • DioException zawiera typ błędu do szczegółowej obsługi awarii
  • Postęp onSendProgress i onReceiveProgress wyświetla stan przesyłania

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również