Avez-vous une question? (216) 97 656 803 hajjriadh@gmail.com
Flutter

Architecture Client-Serveur : Flutter et Spring Boot

Un cours complet pour maîtriser Architecture Client-Serveur : Flutter et Spring Boot.

0 chapitres 0 QCM Accès gratuit
 
  1. Objectif

    • À la fin de ce tutoriel, vous serez capable de :
      • Comprendre le principe de l'architecture client-serveur
      • Configurer un serveur Spring Boot avec une API REST
      • Développer une application Flutter consommant l'API
      • Gérer la communication et les échanges de données
      • Gérer les erreurs et la sécurité basique
  2. Partie 1 : Architecture Client-Serveur - Théorie

    1. Définition du Modèle Client-Serveur
      • Le modèle Client–Serveur est une architecture logicielle qui sépare clairement les responsabilités entre deux parties principales :
        1. Client (Flutter)

          • Le client correspond à l’application que l’utilisateur utilise directement.
            • Application mobile / desktop développée avec Flutter.
            • Interface utilisateur (UI) permettant l’interaction avec l’utilisateur.
            • Envoie des requêtes HTTP (GET, POST, PUT, DELETE) vers le serveur.
          • Reçoit les réponses (souvent au format JSON) et les affiche sous forme lisible (liste, tableau, formulaire…).
    2. Serveur (Spring Boot)

      • Le serveur est la partie backend qui centralise la logique métier.
        • Traite les requêtes envoyées par le client.
        • Gère la logique métier (validation, calculs, règles d’entreprise).
        • Accède à la base de données pour lire, écrire, modifier ou supprimer des informations.
        • Renvoie des réponses au client (succès, erreur, données demandées).
    3. Flutter (Client) = interface et interaction avec l’utilisateur.
    4. Spring Boot (Serveur) = traitement des données et communication avec la base.
  3. Schéma de Communication : Flutter ↔ Spring Boot ↔ Base de Données

    • 1. Envoi de la requête (Client → Serveur)
      • L’utilisateur interagit avec l’application Flutter (exemple : appuie sur "Voir les utilisateurs").
      • Flutter envoie une requête HTTP GET vers le serveur Spring Boot (exemple : http://localhost:8080/api/users).
      • Cette requête demande au serveur des informations précises.
    • 2. Traitement côté serveur (Spring Boot)
      • Spring Boot reçoit la requête.
      • Il applique la logique métier (ex. vérifier les droits d’accès, appliquer des règles, etc.).
      • Ensuite, Spring Boot interroge la base de données MySQL via JPA/Hibernate.
      • La base renvoie les données demandées (ex. liste d’utilisateurs).
    • 3. Réponse du serveur (Serveur → Client)
      • Spring Boot convertit les données récupérées en format JSON.
      • Il renvoie la réponse au client Flutter.
      • Flutter reçoit ce JSON, le décode et l’affiche à l’utilisateur (ex. une liste d’utilisateurs dans un ListView).
  4. Protocole de Communication
    • HTTP/HTTPS: Protocole de transport
    • REST: Architecture d'API
    • JSON: Format d'échange de données
    • Stateless: Chaque requête est indépendante
  • API REST : Explication Complète

    1. Définition Simple
      • Une API REST est comme un serveur dans un restaurant :
        • Le client (Flutter) consulte le menu (endpoints API)
        • Il passe commande (requête HTTP)
        • Le serveur (Spring Boot) comprend la commande, va en cuisine (base de données)
        • Il rapporte le plat (réponse JSON/XML)
        • Chaque interaction est indépendante : le serveur ne se souvient pas des commandes précédentes
    2. Définition Technique
      • REST (REpresentational State Transfer) est une architecture logicielle qui définit des règles pour créer des services web. Une API REST respecte ces règles pour permettre à des applications de communiquer entre elles via HTTP.
    3. Les 6 Principes Fondamentaux du REST
      1. Architecture Client-Serveur

        • Séparation nette entre le client et le serveur
        • Le client gère l'interface utilisateur
        • Le serveur gère le stockage des données et la logique métier
        • Évolution indépendante possible
      2. Sans État (Stateless)

        • Chaque requête doit contenir toutes les informations nécessaires
        • Le serveur ne garde pas le contexte du client entre les requêtes
        • Exemple : Le token d'authentification doit être envoyé à chaque requête
      3. Mise en Cache (Cacheable)

        • Les réponses doivent indiquer si elles peuvent être mises en cache
        • Améliore les performances et réduit la charge serveur
        • Exemple : Cache-Control: max-age=3600
      4. Interface Uniforme

        • Standardisation de la communication :
          • Identification des ressources (URLs claires)
          • Manipulation via représentations (JSON, XML)
          • Messages auto-descriptifs
          • Hypermedia comme moteur de l'état de l'application (HATEOAS)
      5. Système en Couches

        • Architecture en couches hiérarchisées
        • Le client ignore s’il communique avec le serveur final ou un intermédiaire
        • Permet une meilleure scalabilité et sécurité
      6. Code à la Demande (Optionnel)

        • Possibilité d'envoyer du code exécutable au client
        • Moins utilisé dans les APIs modernes
    4. Structure d'une API REST
      • URLs (Endpoints)
      GET    /api/users       → Liste tous les utilisateurs
      GET    /api/users/1     → Récupère l'utilisateur avec ID=1
      POST   /api/users       → Crée un nouvel utilisateur
      PUT    /api/users/1     → Met à jour l'utilisateur ID=1
      DELETE /api/users/1     → Supprime l'utilisateur ID=1
      	
    5. Méthodes HTTP
    6. MéthodeActionExemple
      GETRécupérerGET /api/products
      POSTCréerPOST /api/products
      PUTMettre à jour (complet)PUT /api/products/1
      PATCHMettre à jour (partiel)PATCH /api/products/1
      DELETESupprimerDELETE /api/products/1
    7. Codes de Statut HTTP
    8. CodeSignificationExemple
      200OK - SuccèsRequête réussie
      201Created - CrééRessource créée
      400Bad RequestDonnées invalides
      401UnauthorizedToken manquant/invalide
      403ForbiddenPermissions insuffisantes
      404Not FoundRessource inexistante
      500Internal ErrorBug côté serveur
    9. Formats de Données
      • JSON (le plus courant)
      {
        "id": 1,
        "name": "Smartphone",
        "price": 299.99,
        "inStock": true
      }
      	
    10. XML (moins utilisé aujourd'hui)
    11. 
        1
        Smartphone
        299.99
        true
      
      	
    12. Exemple Complet : API de Produits
      • GET /api/products (Lister tous les produits)
      GET /api/products HTTP/1.1
      Host: api.moncommerce.com
      Authorization: Bearer <token>
      
      Réponse :
      
      HTTP/1.1 200 OK
      Content-Type: application/json
      
      [
        { "id": 1, "name": "Smartphone", "price": 299.99 },
        { "id": 2, "name": "Laptop", "price": 899.99 }
      ]
      	
    13. POST /api/products (Créer un produit)
    14. POST /api/products HTTP/1.1
      Host: api.moncommerce.com
      Content-Type: application/json
      Authorization: Bearer <token>
      
      {
        "name": "Tablet",
        "price": 199.99
      }
      
      Réponse :
      
      HTTP/1.1 201 Created
      Content-Type: application/json
      Location: /api/products/3
      
      {
        "id": 3,
        "name": "Tablet",
        "price": 199.99
      }
      	
    15. Avantages des APIs REST
      • Simplicité : Utilise le protocole HTTP standard
      • Interopérabilité : Compatible avec tous les langages et plateformes
      • Scalabilité : Architecture sans état, facile à scaler
      • Flexibilité : Supporte plusieurs formats (JSON, XML)
      • Performance : Mise en cache native HTTP
    16. REST vs Alternatives
      • REST vs SOAP
      • AspectRESTSOAP
        FormatJSON, XMLXML seulement
        PerformanceLégerLourd
        Courbe d'apprentissageFacileComplexe
        FlexibilitéÉlevéeFaible
      • REST vs GraphQL
      • AspectRESTGraphQL
        RequêtesMultiple endpointsSingle endpoint
        DonnéesFixeFlexible
        ComplexitéSimpleModérée
        CachingHTTP natifPersonnalisé
    17. Sécurité d'une API REST
      • Authentification
        • Tokens JWT
        • OAuth2 pour autorisation déléguée
        • API Keys
      • Protection
        • HTTPS obligatoire
        • Validation des entrées
        • Rate Limiting
        • Configuration CORS
    18. Outils pour APIs REST
      • Postman → Test et documentation
      • Swagger/OpenAPI → Documentation automatique
      • curl → Ligne de commande
  • Qu'est-ce qu'un endpoint API ?

    1. Définitions
      • Un endpoint API est un point d'accès spécifique à une API (Application Programming Interface) qui permet à différentes applications de communiquer entre elles. Chaque endpoint correspond à une URL spécifique qui expose une ressource ou une fonctionnalité particulière.
      • Analogie avec un restaurant
      • Imaginez une API comme le menu d'un restaurant :
        • L'API est le menu entier
        • Chaque endpoint est un plat spécifique du menu
        • La requête est la commande passée par le client
        • La réponse est le plat servi par le restaurant
      • Dans le contexte du développement web, les endpoints API permettent à votre application frontend (comme une app Flutter) de communiquer avec le backend (comme Spring Boot) pour récupérer, créer, modifier ou supprimer des données.
    2. Structure d'un endpoint API
      • Un endpoint API est généralement constitué de plusieurs éléments :
      • Exemple d'endpoint API complet
        • GET https://api.example.com/users/123/posts?published=true&limit=5
          • Protocole: https://
          • Domaine: api.example.com
          • Chemin: /users/123/posts
          • Paramètres de requête: ?published=true&limit=5
      • Composants principaux
        • Méthode HTTP : Définit le type d'opération (GET, POST, PUT, DELETE, etc.)
        • URL de base: Point d'entrée principal de l'API (ex: https://api.example.com)
        • Chemin de la ressource: Spécifie la ressource cible (ex: /users/123/posts)
        • Paramètres: Filtres, options ou données supplémentaires
    3. Méthodes HTTP et leurs utilisations
      • Les endpoints API utilisent différentes méthodes HTTP :
        • GET: Récupérer des données (lecture seule)
        • POST : Créer une nouvelle ressource
        • PUT : Mettre à jour une ressource existante (remplacement complet)
        • PATCH : Mettre à jour partiellement une ressource
        • DELETE: Supprimer une ressource
      • Exemples concrets
        • GET /api/users → Récupère la liste des utilisateurs
        • GET /api/users/42 → Récupère l’utilisateur avec l’ID 42
        • POST /api/users → Crée un nouvel utilisateur
        • PUT /api/users/42 → Met à jour complètement l’utilisateur 42
        • DELETE /api/users/42 → Supprime l’utilisateur 42
    4. Bonnes pratiques pour concevoir des endpoints API
      • Utiliser des noms pluriels : /api/users plutôt que /api/user
      • Hiérarchie logique : /api/users/123/posts pour les posts de l’utilisateur 123
      • Versioning de l’API : /api/v1/users
      • Utiliser des verbes pour les actions complexes : /api/users/123/activate
      • Filtres et pagination : /api/users?active=true&page=2&limit=20
      • Utiliser les bons codes HTTP (200, 201, 400, 404, 500, etc.)
    5. Exemple complet avec Spring Boot et Flutter
      1. Côté Spring Boot (Backend)

          @RestController
          @RequestMapping("/api/users")
          public class UserController {
              
              @Autowired
              private UserService userService;
              
              @GetMapping
              public List getAllUsers() {
                  return userService.getAllUsers();
              }
              
              @GetMapping("/{id}")
              public User getUserById(@PathVariable Long id) {
                  return userService.getUserById(id);
              }
              
              @PostMapping
              public User createUser(@RequestBody User user) {
                  return userService.createUser(user);
              }
          }
          
      2. Côté Flutter (Frontend)

          class ApiService {
            static const String baseUrl = "http://10.0.2.2:8080/api";
            
            static Future> getUsers() async {
              final response = await http.get(Uri.parse('$baseUrl/users'));
              if (response.statusCode == 200) {
                List data = json.decode(response.body);
                return data.map((json) => User.fromJson(json)).toList();
              } else {
                throw Exception('Erreur lors du chargement des utilisateurs');
              }
            }
            
            static Future createUser(User user) async {
              final response = await http.post(
                Uri.parse('$baseUrl/users'),
                headers: {'Content-Type': 'application/json'},
                body: json.encode(user.toJson()),
              );
              if (response.statusCode == 201) {
                return User.fromJson(json.decode(response.body));
              } else {
                throw Exception('Erreur lors de la création');
              }
            }
          }