Baue einen professionellen Netzwerkaufruf mit dem Paket http auf: Timeout, Statuscodes, typisierte Dekodierung und vollständige Zustände.
Diese Lektion in Kodokon öffnenDas Paket http deckt das Wesentliche ab: Anfragen, Header, Body. dio ergänzt Interceptors, Abbruch und Wiederholversuche, auf Kosten einer schwereren Abhängigkeit - eine gute Wahl, sobald die App über ein paar Endpunkte hinauswächst. Egal welcher Client: Der Aufbau eines seriösen Netzwerkaufrufs bleibt derselbe - ein Timeout, eine Prüfung des HTTP-Statuscodes, eine typisierte Dekodierung und drei Bildschirmzustände (Laden, Fehler, Daten), die ausdrücklich behandelt werden.
flutter pub add httpimport 'dart:convert';
import 'package:http/http.dart' as http;
class Article {
const Article({required this.title});
factory Article.fromJson(Map<String, dynamic> json) =>
Article(title: json['title'] as String);
final String title;
}
Future<List<Article>> fetchArticles() async {
final uri = Uri.https('api.example.com', '/articles');
final response = await http
.get(uri)
.timeout(const Duration(seconds: 8));
if (response.statusCode != 200) {
throw Exception('HTTP ${response.statusCode}');
}
final body = utf8.decode(response.bodyBytes);
final data = jsonDecode(body) as List<dynamic>;
return [
for (final item in data)
Article.fromJson(item as Map<String, dynamic>),
];
}Zwei Verhaltensweisen überraschen viele. Erstens: http wirft bei einem Status 404 oder 500 keine Ausnahme - aus Sicht des Netzwerks ist die Anfrage "gelungen", also musst du statusCode selbst prüfen. Zweitens: jsonDecode liefert dynamic; caste sofort (as List<dynamic>, as Map<String, dynamic>), um die Typisierung wiederherzustellen. Bei großen Datenmengen lagerst du die Dekodierung mit compute in ein Isolate aus, damit die UI nicht einfriert.
Bleibt noch, den Zustand des Bildschirms abzubilden. Boolesche Flags wie isLoading in Kombination mit error != null landen immer in widersprüchlichen Zuständen (Laden und Fehler gleichzeitig). Eine sealed-Klasse macht die Zustände wechselseitig ausschließend und das switch vollständig: Wenn du morgen einen Zustand ergänzt, zeigt dir der Compiler jeden Bildschirm, den du anpassen musst.
import 'package:flutter/material.dart';
sealed class ArticlesState {
const ArticlesState();
}
class ArticlesLoading extends ArticlesState {
const ArticlesLoading();
}
class ArticlesError extends ArticlesState {
const ArticlesError(this.message);
final String message;
}
class ArticlesLoaded extends ArticlesState {
const ArticlesLoaded(this.titles);
final List<String> titles;
}
Widget buildArticlesBody(ArticlesState state) {
return switch (state) {
ArticlesLoading() => const Center(
child: CircularProgressIndicator(),
),
ArticlesError(:final message) => Center(
child: Text(message),
),
ArticlesLoaded(:final titles) => ListView.builder(
itemCount: titles.length,
itemBuilder: (context, index) => ListTile(
title: Text(titles[index]),
),
),
};
}http.get-Aufruf erhält eine 500-Antwort. Was macht das Paket http?try/catch abfangen kannst.Response ganz normal zurück: Du musst statusCode selbst prüfen.jsonDecode beherrscht UTF-8 nicht.response.body wird dann als latin-1 dekodiert; verwende utf8.decode(response.bodyBytes).sealed-Klasse, um den Zustand eines Bildschirms zu modellieren?switch wird vollständig: Der Compiler meldet jeden nicht behandelten Zustand.