[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-gestire-le-chiamate-di-rete-in-flutter-con-dio":3,"comments-article-gestire-le-chiamate-di-rete-in-flutter-con-dio":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},2,"Gestire le chiamate di rete in Flutter con Dio","gestire-le-chiamate-di-rete-in-flutter-con-dio","Scopri come effettuare richieste HTTP robuste in Flutter usando il pacchetto Dio: configurazione, interceptor, gestione degli errori e annullamento delle richieste.","## Introduzione\r\n\r\nQuasi ogni app moderna comunica con un backend tramite API REST. In Flutter possiamo usare il pacchetto ufficiale `http`, ma quando le esigenze crescono — interceptor, timeout, retry, annullamento — il pacchetto [Dio](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fdio) diventa la scelta più produttiva.\r\n\r\nIn questo articolo vedremo come configurare Dio, organizzare un client riutilizzabile e gestire correttamente gli errori.\r\n\r\n## Installazione\r\n\r\nAggiungi la dipendenza al tuo `pubspec.yaml`:\r\n\r\n```yaml\r\ndependencies:\r\n  dio: ^5.7.0\r\n```\r\n\r\nEsegui poi `flutter pub get`.\r\n\r\n## Una prima richiesta\r\n\r\nIl modo più semplice per iniziare:\r\n\r\n```dart\r\nimport 'package:dio\u002Fdio.dart';\r\n\r\nfinal dio = Dio();\r\n\r\nFuture\u003Cvoid> fetchPost() async {\r\n  final response = await dio.get(\r\n    'https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fposts\u002F1',\r\n  );\r\n  print(response.data); \u002F\u002F Map già decodificata dal JSON\r\n}\r\n```\r\n\r\nUna differenza importante rispetto al pacchetto `http`: Dio **decodifica automaticamente** il JSON, restituendo direttamente una `Map` o una `List`.\r\n\r\n## Configurare un client riutilizzabile\r\n\r\nÈ buona pratica creare una singola istanza di Dio configurata con la base URL e i timeout:\r\n\r\n```dart\r\nDio createDio() {\r\n  return Dio(\r\n    BaseOptions(\r\n      baseUrl: 'https:\u002F\u002Fapi.example.com\u002Fv1\u002F',\r\n      connectTimeout: const Duration(seconds: 10),\r\n      receiveTimeout: const Duration(seconds: 10),\r\n      headers: {\r\n        'Accept': 'application\u002Fjson',\r\n      },\r\n    ),\r\n  );\r\n}\r\n```\r\n\r\nIn questo modo le chiamate diventano più sintetiche:\r\n\r\n```dart\r\nfinal response = await dio.get('users\u002F42');\r\n```\r\n\r\n## Gli interceptor\r\n\r\nGli interceptor sono il punto di forza di Dio: permettono di intervenire prima della richiesta, dopo la risposta o in caso di errore. Un caso classico è aggiungere il token di autenticazione:\r\n\r\n```dart\r\ndio.interceptors.add(\r\n  InterceptorsWrapper(\r\n    onRequest: (options, handler) {\r\n      final token = readTokenFromStorage();\r\n      if (token != null) {\r\n        options.headers['Authorization'] = 'Bearer $token';\r\n      }\r\n      return handler.next(options);\r\n    },\r\n    onError: (error, handler) {\r\n      if (error.response?.statusCode == 401) {\r\n        \u002F\u002F qui potremmo tentare un refresh del token\r\n      }\r\n      return handler.next(error);\r\n    },\r\n  ),\r\n);\r\n```\r\n\r\nPer il debug è comodo il `LogInterceptor` integrato:\r\n\r\n```dart\r\ndio.interceptors.add(LogInterceptor(responseBody: true));\r\n```\r\n\r\n## Gestione degli errori\r\n\r\nDio lancia un'eccezione di tipo `DioException` quando qualcosa va storto. Possiamo distinguere i vari casi tramite il campo `type`:\r\n\r\n```dart\r\nFuture\u003CUser?> getUser(String id) async {\r\n  try {\r\n    final response = await dio.get('users\u002F$id');\r\n    return User.fromJson(response.data);\r\n  } on DioException catch (e) {\r\n    switch (e.type) {\r\n      case DioExceptionType.connectionTimeout:\r\n      case DioExceptionType.receiveTimeout:\r\n        throw Exception('Timeout di rete, riprova.');\r\n      case DioExceptionType.badResponse:\r\n        final code = e.response?.statusCode;\r\n        throw Exception('Errore del server: $code');\r\n      case DioExceptionType.connectionError:\r\n        throw Exception('Nessuna connessione.');\r\n      default:\r\n        throw Exception('Errore imprevisto: ${e.message}');\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n## Annullare una richiesta\r\n\r\nQuando l'utente lascia una pagina mentre una chiamata è in corso, è utile annullarla per risparmiare risorse. Si usa un `CancelToken`:\r\n\r\n```dart\r\nfinal cancelToken = CancelToken();\r\n\r\ndio.get('search?q=flutter', cancelToken: cancelToken);\r\n\r\n\u002F\u002F Quando serve annullare, ad esempio in dispose():\r\ncancelToken.cancel('Schermata chiusa');\r\n```\r\n\r\n## Inviare dati con POST\r\n\r\nL'invio di un corpo JSON è altrettanto immediato:\r\n\r\n```dart\r\nfinal response = await dio.post(\r\n  'users',\r\n  data: {\r\n    'name': 'Mario',\r\n    'email': 'mario@example.com',\r\n  },\r\n);\r\n```\r\n\r\nPer i caricamenti di file si usa `FormData`:\r\n\r\n```dart\r\nfinal formData = FormData.fromMap({\r\n  'avatar': await MultipartFile.fromFile('\u002Fpath\u002Fto\u002Fimg.png'),\r\n});\r\nawait dio.post('upload', data: formData);\r\n```\r\n\r\n## Conclusione\r\n\r\nDio offre un'esperienza completa per la gestione delle chiamate di rete in Flutter: configurazione centralizzata, interceptor, gestione granulare degli errori e annullamento delle richieste. Per progetti di una certa dimensione, vale la pena costruire un piccolo livello di servizio che incapsuli l'istanza di Dio, separando la logica di rete dal resto dell'app. Il prossimo passo naturale è combinare Dio con un generatore come `retrofit` per definire le API in modo dichiarativo.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Feb2c0fd6-1541-4992-afd4-009c4a832f49.jpg",null,"published","2026-06-06T07:13:00+00:00","Chiamate di rete in Flutter con Dio: guida pratica","Impara a gestire le richieste HTTP in Flutter con Dio: configurazione, interceptor, gestione errori, annullamento e upload di file con esempi in Dart.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":4,"name":20},"Fabio",[],1781247857000]