LAB FLUTTER API REST Page 1
LAB · FLUTTER · API REST · 1H45
Integrer & consommer des
API REST dans Flutter
Guide pas-a-pas pour connecter une application mobile Flutter a une API REST publique, de zero jusqu'a
l'affichage de donnees dynamiques.
●
● Duree : 1h45 ● Flutter + Dart ● OpenWeatherMap Debutant/Intermediaire
SOMMAIRE
01 Introduction aux API REST 15 min
02 Mise en place du projet Flutter 15 min
03 Consommer une API REST 25 min
04 Parsing JSON & affichage UI 25 min
05 Gestion des erreurs & bonnes pratiques 10 min
06 Defi etudiant & questions
01 Introduction aux API REST ■ 15 min
QU'EST-CE QU'UNE API ?
Une API est un contrat entre deux applications definissant comment elles communiquent. Dans ce lab : Flutter
demande la meteo → OpenWeatherMap repond en JSON.
LES METHODES HTTP
GET POST PUT DELETE
Recuperer donnees Envoyer / creer Modifier Supprimer
Dans ce lab, nous n'utilisons que GET — on lit la meteo, on ne la cree pas.
STRUCTURE D'UNE REPONSE JSON
[Link] Données retournées
{
"name": "Dakar", // nom de la ville
"main": { "temp": 30.5, "humidity": 72 },
"weather": [{"description": "ciel degage", "icon": "01d"}],
"wind": {"speed": 4.2}
}
Retenir : JSON = paires cle: valeur. Valeurs : textes, nombres, tableaux [], objets {}.
[Link] · [Link] · [Link] · [Link]/packages/http
LAB FLUTTER API REST Page 2
CYCLE D'UNE REQUETE
App Flutter → HTTP GET → Serveur API → JSON → Affichage UI
02 Mise en place du projet Flutter ■ 15 min
CREER LE PROJET
terminal
flutter create meteo_app
code meteo_app
STRUCTURE RECOMMANDEE
Structure du projet
lib/
■■■ [Link]
■■■ models/weather_model.dart // Classe Weather
■■■ services/weather_service.dart // Appels HTTP
■■■ screens/ // UI
■■■ home_screen.dart
■■■ weather_screen.dart
Regle d'or : separer models / services / screens. Ne jamais les melanger.
AJOUTER LE PACKAGE http
[Link]
dependencies:
flutter:
sdk: flutter
http: ^1.2.0 # <- Ajouter cette ligne
terminal
flutter pub get
Sur Android, ajouter :
03 Consommer une API REST ■ 25 min
L'URL DE L'API OPENWEATHERMAP
URL
[Link]
?q=Dakar &appid=VOTRE_CLE &units=metric &lang=fr
[Link] · [Link] · [Link] · [Link]/packages/http
LAB FLUTTER API REST Page 3
LE SERVICE weather_service.dart
Ce fichier contient toute la logique reseau. Une seule responsabilite : appeler l'API et retourner un Weather.
services/weather_service.dart
import 'dart:convert'; // ① jsonDecode
import 'package:http/[Link]' as http; // ② alias
class WeatherService {
final String apiKey = 'VOTRE_CLE_API';
Future<Weather> fetchWeather(String city) async { // ③
final response = await [Link](
[Link]('[Link]
);
if ([Link] == 200) { // ④ 200=succes
final data = jsonDecode([Link]); // ⑤ decode JSON
return [Link](data); // ⑥ creer objet
} else {
throw Exception('Ville introuvable'); // ⑦ erreur
}
}
}
# Concept Explication
① dart:convert jsonDecode() convertit une chaine JSON en Map Dart
② as http Alias pour eviter les conflits de noms
③ async/await Reseau asynchrone. Future = promesse. await = attend sans bloquer l'UI
④ statusCode 200 200=succes, 404=introuvable, 401=non autorise, 500=erreur serveur
⑤ jsonDecode Convertit [Link] (String) en Map
⑥ fromJson Delegue la construction de l'objet au modele
⑦ throw Exception Propage l'erreur vers FutureBuilder
04 Parsing JSON & affichage UI ■ 25 min
LE MODELE weather_model.dart
Le modele represente un objet metier. Il contient les donnees et sait se construire depuis un JSON.
models/weather_model.dart
[Link] · [Link] · [Link] · [Link]/packages/http
LAB FLUTTER API REST Page 4
class Weather {
final String city; final double temperature;
final String description; final int humidity;
final double windSpeed; final String icon;
Weather({required [Link], required [Link], // ①
required [Link], required [Link],
required [Link], required [Link]});
factory [Link](Map<String, dynamic> json) { // ②
return Weather(
city: json['name'],
temperature: json['main']['temp'].toDouble(),
description: json['weather'][0]['description'], // ③
humidity: json['main']['humidity'],
windSpeed: json['wind']['speed'].toDouble(),
icon: json['weather'][0]['icon'],
);
}
}
# Concept Explication
① required Force la fourniture de tous les champs. Erreur de compilation si manquant.
② factory Constructeur special pour deserialiser JSON → objet Dart.
[ Tableau json['weather'][0] = premier element du tableau 'weather'.
0
]
FUTUREBUILDER — LE WIDGET ASYNCHRONE CLE
FutureBuilder gere automatiquement les 3 etats d'un appel reseau.
FutureBuilder
FutureBuilder<Weather>(
future: [Link](city),
builder: (context, snapshot) {
// ① Chargement
if ([Link] == [Link])
return const CircularProgressIndicator();
// ② Erreur
if ([Link])
return Text('Erreur : ${[Link]}');
// ③ Succes
final weather = [Link]!;
return Text([Link]);
},
)
waiting hasError data ✓
Afficher loader Afficher erreur Afficher UI
ECRAN weather_screen.dart
[Link] · [Link] · [Link] · [Link]/packages/http
LAB FLUTTER API REST Page 5
screens/weather_screen.dart
class WeatherScreen extends StatelessWidget {
final String city;
const WeatherScreen({[Link], required [Link]});
@override
Widget build(BuildContext context) {
final service = WeatherService();
return Scaffold(
appBar: AppBar(title: Text(city)),
body: FutureBuilder<Weather>(
future: [Link](city),
builder: (context, snapshot) {
if ([Link] == [Link])
return const Center(child: CircularProgressIndicator());
if ([Link])
return const Center(child: Text('Erreur de chargement'));
final weather = [Link]!;
return Padding(padding: const [Link](16),
child: Card(child: Column(children: [
Text([Link], style: TextStyle(fontSize:28, fontWeight:[Link])),
[Link]('[Link]
Text('${[Link]} degC', style: TextStyle(fontSize:40)),
Text([Link], style: TextStyle(fontSize:20)),
Row(mainAxisAlignment: [Link], children: [
Column(children:[Icon(Icons.water_drop),Text('${[Link]}%')]),
Column(children:[Icon([Link]),Text('${[Link]} m/s')]),
]),
])),
);
},
),
);
}
}
WIDGETS UTILISES DANS CE PROJET
Widget Role
Text Afficher du texte avec style personnalisable
Card Conteneur avec ombre et bords arrondis
[Link] Charger et afficher une image depuis une URL
Column / Row Disposer des widgets verticalement / horizontalement
CircularProgressIndicator Spinner pendant l'appel reseau
TextField Champ de saisie utilisateur
ElevatedButton Bouton Material Design
SnackBar Message temporaire en bas d'ecran
[Link] · [Link] · [Link] · [Link]/packages/http
LAB FLUTTER API REST Page 6
[Link] Naviguer vers un nouvel ecran
05 Gestion des erreurs & bonnes pratiques ■ 10 min
LES CAS D'ERREUR A ANTICIPER
Erreur Cause Reponse recommandee
Pas d'internet SocketException Verifiez votre connexion
Ville inexistante statusCode 404 Ville introuvable
Cle API invalide statusCode 401 Erreur d'authentification
Timeout TimeoutException Delai depasse, reessayez
Erreur serveur statusCode 500+ Service indisponible
BONNES PRATIQUES D'ARCHITECTURE
A FAIRE A EVITER
• Separer models / services / screens • Mettre le code HTTP dans les widgets UI
• Gerer les 3 etats du FutureBuilder • Afficher sans verifier [Link]
• Mettre la cle API dans un fichier config • Commiter la cle API dans Git
• Utiliser final pour les proprietes immuables • Dupliquer la logique reseau par ecran
• Extraire les grands widgets en sous-widgets • Creer des widgets de 300+ lignes
06 Defi etudiant & questions
DEFI — EXTENSIONS DU PROJET
Niveau 1 Niveau 1 Niveau 2
Ajouter la date et l'heure locale Fond selon la meteo (soleil, Mode sombre / clair avec
pluie...) ThemeMode
Niveau 2 Niveau 3 Niveau 3
Historique des villes recherchees Previsions 5 jours (endpoint Geolocalisation de l'utilisateur
/forecast)
QUESTIONS DE REVISION
# Question
Q1 Quelle difference entre une API et une base de donnees ?
Q2 Pourquoi JSON plutot que XML ?
Q3 Quel est le role exact du FutureBuilder ?
[Link] · [Link] · [Link] · [Link]/packages/http
LAB FLUTTER API REST Page 7
Q4 Pourquoi separer les services des vues ?
Q5 Quelle difference entre GET et POST ?
Q6 Que signifie async/await ? Que se passerait-il sans eux ?
Q7 A quoi sert le factory constructor dans le modele ?
A RETENIR
Concept Resume
API REST Protocole d'echange de donnees via HTTP
package http Envoyer des requetes HTTP depuis Flutter / Dart
jsonDecode Convertir une chaine JSON en Map Dart
Factory constructor Creer un objet Dart depuis un Map JSON
FutureBuilder Gere les 3 etats d'un appel asynchrone
Architecture Toujours separer models / services / screens
[Link] · [Link] · [Link] · [Link]/packages/http
[Link] · [Link] · [Link] · [Link]/packages/http