Parfait 👍 On va faire ça comme un vrai cours, progressif, structuré, pour qu’à la fin tu sois
100 % autonome pour implémenter n’importe quelle API REST en Flutter (OpenAI, Stripe,
Firebase REST, API locale, etc.).
Je vais partir de zéro, expliquer chaque concept, puis te donner une méthode universelle que
tu pourras réutiliser partout.
🎓 COURS COMPLET : Implémenter des API REST en Flutter
(de A à Z)
🧠 CHAPITRE 1 — C’est quoi une API REST (vraiment)
1 REST = communication client ↔ serveur via HTTP
1️⃣
Flutter = client Serveur = API REST
La communication se fait via :
• URL
• Méthodes HTTP
• Headers
• Body
• Réponse JSON
2️⃣Les méthodes HTTP (indispensable)
Méthode Usage
GET Lire des données
POST Créer / envoyer
PUT Mettre à jour
PATCH Mise à jour partielle
DELETE Supprimer
OpenAI → POST Login → POST Liste de produits → GET
3️⃣Format des données : JSON
{
"name": "Paul",
1
"age": 25
}
Flutter travaille avec :
Map<String, dynamic>
🧰 CHAPITRE 2 — Les outils indispensables en Flutter
1️⃣La librairie HTTP
Dans [Link] :
dependencies:
http: ^1.1.0
Import :
import 'package:http/[Link]' as http;
2️⃣Convertir JSON ↔ Dart
import 'dart:convert';
Fonction Rôle
jsonEncode Dart → JSON
jsonDecode JSON → Dart
3️⃣Les variables d’environnement (sécurité)
flutter_dotenv: ^5.1.0
API_KEY=xxxxx
🌍 CHAPITRE 3 — Anatomie complète d’un appel API REST
Exemple SIMPLE (GET)
final response = await [Link](
[Link]('[Link]
);
Analyse :
• [Link] → requête HTTP
• [Link] → transforme l’URL
• await → attend la réponse
2
Lire la réponse
print([Link]); // 200, 401, 500...
print([Link]); // JSON String
Décoder le JSON
final data = jsonDecode([Link]);
📨 CHAPITRE 4 — POST request (le plus important)
Exemple générique universel
Future<Map<String, dynamic>> postRequest({
required String url,
required Map<String, dynamic> body,
Map<String, String>? headers,
}) async {
final response = await [Link](
[Link](url),
headers: {
'Content-Type': 'application/json',
...?headers,
},
body: jsonEncode(body),
);
if ([Link] != 200) {
throw Exception([Link]);
}
return jsonDecode([Link]);
}
👉 Ce pattern marche pour 90 % des API REST.
🧱 CHAPITRE 5 — Structurer le code proprement (IMPORTANT)
❌ Mauvais (dans le UI)
onPressed: () async {
final response = await [Link](...);
}
3
✅ Bon (Service)
class ApiService {
Future<Map<String, dynamic>> post(...) async { ... }
}
UI → Service → API
🧪 CHAPITRE 6 — Créer un modèle (DTO)
Exemple réponse API
{
"id": 1,
"name": "Paul"
}
Modèle Dart
class UserModel {
final int id;
final String name;
UserModel({required [Link], required [Link]});
factory [Link](Map<String, dynamic> json) {
return UserModel(
id: json['id'],
name: json['name'],
);
}
}
🔄 CHAPITRE 7 — Pattern universel pour TOUTES les API REST
Étape 1 — Lire la documentation API
Tu dois toujours identifier :
• URL
• Méthode
• Headers
• Body
• Réponse
4
Étape 2 — Créer le service
class ApiService {
static const baseUrl = '[Link]
Future<Map<String, dynamic>> postData(...) async { ... }
}
Étape 3 — Créer les modèles
[Link](...)
Étape 4 — Connecter au UI
final data = await [Link]();
🤖 CHAPITRE 8 — Implémenter OpenAI (application directe)
Documentation OpenAI te dit :
• POST
• URL
• Headers
• Body JSON
Tu traduis mot pour mot en Dart :
final response = await [Link](
[Link](url),
headers: headers,
body: jsonEncode(body),
);
💡 Toutes les API REST fonctionnent exactement comme ça.
CHAPITRE 9 — Gestion des erreurs (niveau pro)
if ([Link] >= 400) {
throw ApiException([Link]);
}
5
🚀 CHAPITRE 10 — Tu es maintenant AUTONOME si tu sais faire ça
Tu sais implémenter une API REST si tu peux répondre à ces questions :
✅ Quelle est l’URL ? ✅ Quelle méthode HTTP ? ✅ Quels headers ? ✅ Quel body ? ✅ Quel type
de réponse JSON ?
👉 Si tu sais ça, tu peux coder n’importe quelle API.
🧠 MÉTHODE MENTALE À RETENIR (TRÈS IMPORTANT)
Quand tu vois une API REST, pense toujours :
1. Endpoint
2. Méthode
3. Headers
4. Body
5. Response
6. JSON → Model
🏁 CONCLUSION
• Flutter REST = HTTP + JSON + async/await
• [Link]() est ton meilleur ami
• OpenAI = une API REST comme les autres
• La différence est seulement dans le body JSON
• Si tu comprends ce cours → tu peux tout faire
🔥 Prochaine étape (je te propose)
Je peux maintenant te faire :
11️⃣Un TP pratique2️⃣
: créer ta propre API REST (fake) et la consommer Un mini-framework
perso3️⃣
pour appeler n’importe quelle API REST Une version Clean Architecture complète
4️⃣
(Service → Repository → UseCase) Un exercice corrigé comme à l’université
👉 Dis-moi ce que tu veux faire maintenant.
Excellentes questions 👌 Tu touches là au cœur de ce qu’on fait vraiment quand on consomme
une API REST. Je vais répondre sans jargon inutile, avec des analogies, puis techniquement,
pour que ce soit définitivement clair.
6
1 C’est quoi parse en réalité ?
1️⃣
👉 Parse = analyser + transformer
Le mot parse signifie :
Prendre une donnée brute (souvent un texte) et la transformer en une structure
comprise par la machine
Exemples simples :
• Parser une date → "2025-01-01" → DateTime
• Parser un JSON → "{"a":1}" → Map
• Parser une URL → "[Link] → Uri
👉 Donc parse ≠ convertir au hasard 👉 parse = donner du sens à une string
2️⃣Pourquoi [Link]("...") au lieu de laisser une String ?
❓ Question clé : Pourquoi [Link] n’accepte pas une String
directement ?
Parce qu’une URL n’est pas juste un texte.
Regarde cette URL :
[Link] de tête&page=1
Elle contient :
• protocole (https)
• hôte ([Link])
• chemin (/search)
• query parameters (q, page)
• encodage (mal de tête → %20)
👉 Une String ne garantit rien de tout ça.
🔹 Ce que fait [Link]()
Uri uri = [Link]("[Link] de tête");
Dart transforme ça en un objet structuré :
[Link] // https
[Link] // [Link]
[Link] // /search
7
[Link] // {q: "mal de tête"}
👉 Et surtout :
• Encode automatiquement les caractères spéciaux (é, espaces, etc.)
• Valide la structure de l’URL
• Évite des bugs réseau
❌ Si on laissait une String brute
[Link]("[Link]
⛔ Problème :
• caractères non valides
• erreurs réseau silencieuses
• sécurité moindre
👉 C’est pour ça que l’API HTTP de Dart exige un Uri, pas une String.
3️⃣Donc : [Link]("dfdsfd") ?
Très bonne remarque 👏
[Link]("dfdsfd")
Ça marche syntaxiquement, mais :
• Dart suppose que c’est une URI relative
• Ce n’est pas une URL valide pour HTTP
• [Link] échouera à l’exécution
📌 [Link] ne valide pas toujours la logique HTTP, il structure la donnée.
4️⃣jsonDecode et jsonEncode — tu es presque juste (corrigeons
finement)
✔️Ce que tu as bien compris
jsonDecode change le JSON (réponse) en Map<String, dynamic>
✅ Exact Mais précision importante :
jsonDecode(String json)
👉 accepte UNIQUEMENT une String JSON valide
8
🔹 Exemple
final map = jsonDecode('{"name":"Paul"}');
Résultat :
Map<String, dynamic>
❌ Ce que jsonDecode NE fait PAS
jsonDecode(123); // ❌
jsonDecode({"a":1}); // ❌
👉 Il ne décode que des Strings JSON.
✔️jsonEncode — rôle réel
Tu as dit :
jsonEncode pour changer la réponse (peu importe son type) en JSON
Presque, mais attention
👉 jsonEncode transforme :
• Map
• List
• int, double, bool, String ➡️en String JSON
Exemple :
jsonEncode({"a": 1});
Résultat :
"{\"a\":1}"
👉 C’est toujours une String.
⚠️Ce que jsonEncode ne garantit PAS
• Que l’API accepte ce JSON
• Que la structure est correcte pour le serveur
Il fait juste :
“Je transforme un objet Dart en texte JSON”
9
5️⃣Pourquoi on encode TOUJOURS le body en JSON ?
Parce que dans HTTP :
• Le body est un texte
• Le serveur ne comprend pas les objets Dart
• Le standard REST = JSON
Donc :
body: jsonEncode(bodyMap)
👉 garantit que :
• tu envoies du texte
• au format attendu (Content-Type: application/json)
6️⃣Schéma mental FINAL (à retenir à vie)
URL (String)
↓ [Link]
Uri (structuré, sûr)
↓ [Link]
HTTP request
↓ [Link] (String JSON)
String JSON
↓ jsonDecode
Map / List (Dart)
7️⃣Résumé ultra simple
Fonction Sert à quoi
parse analyser + structurer une String
[Link] transformer une URL String en objet Uri
jsonEncode Dart → String JSON
jsonDecode String JSON → Dart
[Link] envoie une requête HTTP
8️⃣
Ta compréhension est déjà très bonne
Tu as exactement la bonne intuition, il manquait juste ces précisions :
• parse ≠ gadget
• Uri ≠ String
• JSON = toujours String sur le réseau
10
Si tu veux, prochaine étape je peux t’expliquer :
• 🧠 Pourquoi [Link] est toujours une String
• 🔐 Comment sécuriser et valider un JSON reçu
• 🧩 Comment construire une URL propre avec Uri(...) au lieu de parse
• 🧪 Comment tester une API REST sans UI
Dis-moi ce que tu veux approfondir 👇
Excellente question 👌 Tu es maintenant au bon niveau pour comprendre ça proprement.
👉 Oui, il existe plusieurs genres d’API, et REST n’est qu’un type parmi d’autres. Je vais te
faire une cartographie claire, avec à quoi ça sert, quand les utiliser, et comment elles se
consomment côté Flutter.
LES GRANDS TYPES D’API (VUE GLOBALE)
API
├── HTTP-based
│ ├── REST
│ ├── GraphQL
│ ├── gRPC (HTTP/2)
│ └── RPC classiques
│
├── Realtime
│ ├── WebSocket
│ ├── SSE
│ └── Firebase Realtime
│
├── Local / System
│ ├── Platform Channels
│ └── FFI
│
└── Messaging / Event
├── Message Queue
└── Pub/Sub
1️⃣API REST (déjà vu)
📌 La plus répandue
Caractéristiques
• HTTP (GET, POST, PUT…)
• JSON
• Stateless
• Facile à comprendre
11
Exemple
• OpenAI
• Stripe
• Firebase REST
• APIs gouvernementales
Flutter
[Link]([Link](url))
2️⃣GraphQL API
📌 Alternative moderne à REST
Principe
👉 Le client demande exactement les données dont il a besoin
Exemple requête
query {
user {
name
age
}
}
Avantages
• Moins de données inutiles
• Un seul endpoint
Inconvénients
• Plus complexe à mettre en place
• Cache plus difficile
Flutter
• graphql_flutter
3️⃣gRPC
📌 Ultra performant (microservices)
12
Principe
• Basé sur HTTP/2
• Utilise Protocol Buffers, pas JSON
• Typé fort
• Très rapide
Utilisé par
• Google
• Backend haute performance
Flutter
• grpc
Quand ?
• Apps très grandes
• Temps réel / faible latence
4️⃣WebSocket API (temps réel)
📌 Connexion persistante
Principe
• Connexion ouverte
• Le serveur pousse les données
Exemples
• Chat
• Jeux
• Live tracking
• Trading
Flutter
[Link]([Link](url));
5️⃣SSE (Server-Sent Events)
📌 Temps réel à sens unique
13
Principe
• Le serveur envoie
• Le client écoute
Exemples
• Notifications
• Logs
• Streaming IA (OpenAI streaming)
Flutter
• http + stream
6️⃣Firebase APIs (spécifiques)
📌 APIs “temps réel + sync auto”
Types
• Firebase Auth
• Firestore
• Realtime Database
• Cloud Functions
Avantage
• Pas besoin de gérer HTTP manuellement
• SDK Flutter direct
7️⃣Platform Channels (API locales)
📌 Flutter ↔ Android/iOS natif
Principe
• Appelle du code Java/Kotlin/Swift
• Expose une API locale
Exemple
• Accès capteurs
• Bluetooth bas niveau
14
• SDK non Flutter
8️⃣FFI (Foreign Function Interface)
📌 Appeler du C/C++
Utilisation
• Crypto
• Vision
• Performance extrême
9️⃣Message Queues / Event APIs
📌 Communication asynchrone
Exemples
• RabbitMQ
• Kafka
• MQTT
Usage
• IoT
• systèmes distribués
🔑 COMMENT CHOISIR LE BON TYPE D’API ?
Besoin API recommandée
CRUD simple REST
Données flexibles GraphQL
Temps réel bidirectionnel WebSocket
Streaming serveur SSE
Haute performance gRPC
Mobile rapide Firebase
Accès hardware Platform Channel
15
🎯 POUR TOI (Flutter + Santé + IA)
Je te recommande :
• REST → OpenAI, backend médical
• WebSocket/SSE → streaming IA, chat
• Firebase → auth + stockage
🧠 À retenir absolument
👉 REST est la base 👉 Les autres sont des spécialisations 👉 Si tu maîtrises REST, tu peux
apprendre les autres rapidement
Prochaine étape possible
1️⃣
Je peux : Te montrer le même service2️⃣
implémenté en REST vs GraphQL vs WebSocket
T’expliquer quand REST devient un problème3️⃣Te faire un tableau comparatif pratique4️⃣
Te guider pour implémenter un WebSocket en Flutter
Dis-moi ce que tu veux maintenant 👇
16