Dio est un client HTTP puissant pour Dart et Flutter, créé par l'ingénieur chinois Wenda Wang. La bibliothèque fournit une API avancée avec prise en charge des intercepteurs, FormData, téléchargement de fichiers et annulation de requêtes. Selon pub.dev, 2025, Dio est le client HTTP le plus populaire dans l'écosystème Flutter avec plus de 8 000 étoiles sur GitHub.
Points clés
Dio est une puissante bibliothèque cliente HTTP pour le langage Dart, la plus largement utilisée dans les applications Flutter. Dio fournit une API riche avec prise en charge des intercepteurs, de la configuration globale, des transformateurs, de FormData, du téléchargement de fichiers et de la gestion flexible des délais d'attente, ce qui en fait le choix principal pour les communications réseau dans la communauté Flutter.
La bibliothèque a été créée par Wenda Wang en 2018 comme alternative au HttpClient intégré de dart:io, qui manquait de nombreuses fonctionnalités modernes : configuration unifiée pour toutes les requêtes, intercepteurs et sérialisation automatique. En 2025, Dio a dépassé en popularité le package http de l'équipe Dart, occupant la première place parmi les clients HTTP dans l'écosystème Flutter selon pub.dev.
Dio prend en charge trois adaptateurs : DartNativeAdapter (par défaut sur Android, iOS, Desktop), BrowserAdapter (sur Web) et IOAdapter. L'adaptateur est sélectionné automatiquement en fonction de la plateforme. Dio fournit également une interface unifiée pour toutes les plateformes Flutter — Android, iOS, Web, macOS, Windows et Linux.
L'architecture de Dio est construite sur une chaîne de gestionnaires. Chaque requête passe par une séquence d'intercepteurs qui peuvent modifier la requête (InterceptorsWrapper.onRequest), la réponse (onResponse) ou traiter une erreur (onError). Après les intercepteurs, la requête va aux transformateurs (Transformer), qui transforment les données avant l'envoi.
Une instance de Dio est configurée via un objet BaseOptions contenant l'URL de base, les en-têtes par défaut, les délais d'attente, le type de réponse (JSON, stream, plain), les paramètres de requête et le format des données. Ces paramètres s'appliquent à toutes les requêtes mais peuvent être remplacés dans une requête spécifique. BaseOptions fournit un point de configuration unique pour toute l'application, simplifiant les changements de point d'accès ou l'ajout d'en-têtes globaux.
Chaque requête dans Dio retourne Response<T>, où T est le type de données après le traitement des transformateurs. Par défaut, Dio convertit automatiquement les réponses JSON en Map<String, dynamic>. Pour les réponses typées, Dio est utilisé avec des packages de sérialisation : json_serializable, freezed ou built_value. La Response contient data, headers, statusCode, requestOptions et des données supplémentaires.
La configuration de base est créée via Dio(BaseOptions). On peut définir une baseUrl pour toutes les requêtes, connectTimeout et receiveTimeout, les en-têtes content-type et accept, ainsi que queryParameters. Tous ces paramètres s'appliquent à chaque requête, éliminant la duplication de code et centralisant la gestion des paramètres réseau.
Dio prend en charge deux modes de sérialisation : JSON par défaut (responseType : ResponseType.json) et streaming (ResponseType.stream). En mode stream, Response.data retourne un ResponseBody qui peut être lu par morceaux. C'est pratique pour les fichiers de grande taille dont le chargement complet en mémoire n'est pas souhaitable. Le mode plain retourne une chaîne brute sans analyse JSON automatique.
Les intercepteurs sont le mécanisme clé de Dio pour intercepter et modifier les requêtes, réponses et erreurs. Ils remplacent complètement l'Interceptor d'OkHttp et les plugins de Ktor, mais avec une API spécifique à Dart et un support asynchrone via Future. Les intercepteurs peuvent être ajoutés à la fois dans la configuration globale de Dio et pour des requêtes individuelles.
| Méthode d'intercepteur | Objectif | Exemple d'utilisation |
|---|---|---|
| onRequest | Modifier la requête avant envoi | Ajouter un jeton d'autorisation |
| onResponse | Traiter une réponse réussie | Convertir les données en objets DTO |
| onError | Traiter une erreur de requête | Nouvelle tentative automatique sur 503 |
Le LogInterceptor intégré journalise chaque requête : méthode, URL, en-têtes, corps et temps d'exécution. Il a deux modes : compact (une ligne par requête) et complet (informations complètes avec corps). LogInterceptor est particulièrement utile pendant le développement, mais il est recommandé de le désactiver dans les versions de release via des imports conditionnels ou un indicateur global.
Les intercepteurs personnalisés sont créés via la classe InterceptorsWrapper. On peut redéfinir une, deux ou les trois méthodes (onRequest, onResponse, onError). Dio exécute les intercepteurs strictement dans l'ordre de leur ajout à la liste des intercepteurs. Si un intercepteur n'appelle pas handler.next(), la chaîne est interrompue et la réponse ou l'erreur n'atteint pas l'application.
Pour l'authentification dans Dio, on utilise un intercepteur qui ajoute un jeton Bearer à l'en-tête Authorization. Si le serveur retourne 401, l'intercepteur dans onError tente de renouveler le jeton via une requête de rafraîchissement et répète la requête originale avec le nouveau jeton. Ce modèle est appelé token refresh interceptor et est implémenté via DioException en vérifiant response?.statusCode == 401.
Dio fournit une prise en charge intégrée pour la logique de nouvelle tentative via le package dio_smart_retry ou un RetryInterceptor personnalisé. La nouvelle tentative est importante pour les applications mobiles : lorsque la connexion est perdue pendant 2 à 3 secondes, Dio lance une DioException de type connectionTimeout ou connectionError. RetryInterceptor intercepte cette exception et répète la requête jusqu'à 3 fois avec un backoff exponentiel (1s, 2s, 4s), améliorant la fiabilité de l'application dans des conditions réseau instables.
Examinons une requête GET de base avec Dio. Une instance est créée avec BaseOptions, définissant l'URL de base et les délais d'attente. La requête est exécutée via la méthode get(), retournant une Response avec des données au 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['connexion'])
Pour une requête POST avec un corps JSON, un objet Map ou un DTO personnalisé est passé. Dio sérialise automatiquement le Map en JSON via jsonEncode. Pour les DTO typés, on utilise l'option queryParameters, le champ data ou un Transformer personnalisé.
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'])
Un intercepteur personnalisé ajoute un jeton Bearer à chaque requête. La méthode onRequest se déclenche avant l'envoi, modifiant les en-têtes. Sur une réponse 401, l'intercepteur peut renouveler le jeton et répéter la requête via la méthode 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 simplifie le téléchargement de fichiers via FormData. Pour envoyer un fichier, un MultipartFile est créé à partir de File, Bytes ou AssetBundle. FormData définit automatiquement l'en-tête multipart/form-data avec la bonne limite et le bon encodage. Dio prend en charge la progression du téléversement via onSendProgress.
Pour le téléchargement de fichiers, la méthode download() est utilisée, qui enregistre le flux de données directement dans un fichier. Dio prend en charge la reprise des téléchargements interrompus via l'en-tête Range, ce qui est particulièrement utile pour les fichiers volumineux. La progression du téléchargement est suivie via onReceiveProgress, permettant d'afficher une barre de progression dans l'interface utilisateur.
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('Upload : $progress%')
},
)
// Téléchargement de fichier
await dio.download(
'https://example.com/file.zip',
'/storage/emulated/0/Download/file.zip',
onReceiveProgress: (received, total) {
print('Download : ${received / total * 100}%')
},
)
La gestion incorrecte des erreurs est le problème le plus courant. Dio lance une DioException (anciennement DioError) pour tout problème : indisponibilité réseau, délai d'attente, erreurs HTTP 4xx/5xx. De nombreux développeurs capturent seulement l'Exception générique, perdant des informations sur le type d'erreur et la possibilité de la traiter spécifiquement. Utilisez DioException.type pour déterminer la cause de l'échec.
Ignorer CancelToken entraîne des fuites de requêtes. Si un utilisateur quitte un écran alors qu'une requête est encore en cours, Dio gaspille des ressources et peut tenter de mettre à jour un State détruit. Créez toujours un CancelToken pour chaque requête et annulez-le dans dispose(). CancelToken génère une DioException de type cancel, qui doit être traitée correctement.
Absence de logique de nouvelle tentative pour les pannes temporaires. Sur les appareils mobiles, le réseau est souvent brièvement indisponible. Implémentez un intercepteur avec nouvelle tentative automatique de requête en cas de délai d'attente ou de réponse 503/502. Utilisez RetryInterceptor du package dio_smart_retry ou écrivez un intercepteur personnalisé avec backoff exponentiel entre les tentatives.
Questions fréquentes
Dio fournit des intercepteurs, une configuration globale BaseOptions, FormData, la progression du téléversement et CancelToken. Le package http de l'équipe Dart est minimaliste, sans intercepteurs ni configuration globale. Dio est utilisé dans les grands projets, tandis que http est utilisé pour les scripts simples.
Par défaut, Dio convertit JSON en Map en utilisant jsonDecode. Pour la sérialisation typée, utilisez les packages json_serializable ou freezed. Créez un intercepteur personnalisé qui convertit response.data en DTO via fromJson() dans onResponse.
Créez un CancelToken et passez-le dans les options de la requête. L'appel de token.cancel() interrompt la requête et lance une DioException de type cancel. CancelToken prend en charge l'annulation de plusieurs requêtes simultanément, ce qui est pratique pour annuler toutes les requêtes en quittant un écran.
Oui, Dio fonctionne sur les six plateformes Flutter : Android, iOS, Web, macOS, Windows et Linux. Chaque plateforme utilise un client HTTP adaptatif : DartNativeAdapter (plateformes natives) et BrowserAdapter (Web). Une API unifiée pour toutes les plateformes est un avantage clé de Dio dans les projets Flutter.
Dio ne gère pas les cookies automatiquement. Pour la prise en charge des cookies, utilisez le package dio_cookie_manager avec cookie_jar. CookieManager intercepte les en-têtes Set-Cookie et Cookie et enregistre les cookies dans PersistCookieJar pour un envoi automatique dans les requêtes ultérieures au même domaine.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi