CodeGym /Cours /Docker SELF /Conception de l'architecture d'une application

Conception de l'architecture d'une application

Docker SELF
Niveau 23 , Leçon 1
Disponible

2.1 Architecture générale

À cette étape, on va concevoir l'architecture de l'application de gestion des tâches. On va définir comment le frontend, le backend et la base de données interagiront entre eux, ainsi que les composants inclus dans chacun d'eux.

L'application sera composée de trois principaux composants :

  • Frontend (ReactJS) : la partie client qui permet l'interaction de l'utilisateur avec le système.
  • Backend (Flask) : la partie serveur qui gère les requêtes provenant du frontend et interagit avec la base de données.
  • Database (PostgreSQL) : le stockage des données pour les utilisateurs et les tâches.

L'architecture ressemblera à ceci :

Terminal

+-------------+       +-------------+       +--------------+
|             |       |             |       |              |
|  Frontend   +------->+   Backend   +------->+   Database   |
|  (ReactJS)  |       |   (Flask)   |       | (PostgreSQL) |
|             |       |             |       |              |
+-------------+       +-------------+       +--------------+

Interaction entre les composants

  • Frontend : envoie des requêtes HTTP au backend pour exécuter des opérations CRUD (création, lecture, mise à jour, suppression des tâches).
  • Backend : traite les requêtes HTTP provenant du frontend, exécute la logique métier et interagit avec la base de données.
  • Database : stocke et fournit les données selon les requêtes du backend.

2.2 Description de chaque composant

1. Frontend (ReactJS):

  • Composants de l'interface utilisateur: composants pour l'inscription et l'authentification des utilisateurs, la création et la modification des tâches, la visualisation de la liste des tâches.
  • Interaction avec l'API: utilisation de la bibliothèque Axios pour envoyer des requêtes HTTP au backend.

2. Backend (Flask):

  • REST API: implémentation des endpoints pour la gestion des utilisateurs et des tâches.
  • Modèles de données: définition des modèles de données pour les utilisateurs et les tâches en utilisant SQLAlchemy.
  • Logique métier: gestion de la logique de l'application, y compris la validation des données et la gestion des sessions utilisateur.

3. Base de données (PostgreSQL):

  • Tables: tables pour stocker des informations sur les utilisateurs et les tâches.
  • Relations entre les tables: définition des relations entre les tables des utilisateurs et des tâches (par exemple, un utilisateur peut avoir plusieurs tâches).

4. Interaction réseau

Toute la communication entre les composants se fera via le protocole HTTP. Le frontend interagira avec le backend via le REST API, et le backend interagira avec la base de données via des requêtes SQL.

  • Frontend: port 3000 pour le développement et les tests.
  • Backend: port 5000 pour l'interaction avec le frontend.
  • Base de données: port 5432 pour l'interaction avec le backend.

2.3 Description détaillée de chaque composant

1. Structure de données de base

Pour stocker les données des utilisateurs et des tâches dans la base de données PostgreSQL, on va créer deux tables : users et tasks.

Table users :

  • id (int, primary key) : identifiant unique de l'utilisateur.
  • username (varchar, unique) : nom d'utilisateur.
  • password (varchar) : hash du mot de passe de l'utilisateur.

Table tasks :

  • id (int, primary key) : identifiant unique de la tâche.
  • title (varchar) : titre de la tâche.
  • description (text) : description de la tâche.
  • owner_id (int, foreign key) : identifiant de l'utilisateur assigné à la tâche.
  • status (varchar) : statut de la tâche (par exemple, terminée/non terminée).

2. Design de l'API

Le backend fournira une RESTful API pour interagir avec le frontend. Liste approximative des endpoints :

  • Utilisateurs :
    • POST /users : création d'un nouvel utilisateur.
    • GET /users : récupération de la liste de tous les utilisateurs.
    • GET /users/:id : récupération des infos d'un utilisateur spécifique.
    • PUT /users/:id : mise à jour des infos de l'utilisateur.
    • DELETE /users/:id : suppression de l'utilisateur.
  • Tâches :
    • POST /tasks : création d'une nouvelle tâche.
    • GET /tasks : récupération de la liste de toutes les tâches.
    • GET /tasks/:id : récupération des infos d'une tâche spécifique.
    • PUT /tasks/:id : mise à jour des infos de la tâche.
    • DELETE /tasks/:id : suppression de la tâche.

2.4 Modèles de données

Voici à quoi ressemble le code en Python pour travailler avec des tables de base de données :

User Model :

Python

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    tasks = db.relationship('Task', backref='owner', lazy=True)
    def to_dict(self):
        return {
            "id": self.id,
            "username": self.username
        }

Task Model :

Python

from app import db

class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    description = db.Column(db.Text, nullable=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    status = db.Column(db.String(20), nullable=False, default="non terminée")
    def to_dict(self):
        return {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "owner_id": self.owner_id,
            "status": self.status
        }

2.5 Routes et contrôleurs

Exemple d'implémentation d'une API côté serveur :

Python

from app import app, db
from app.models import Task, User
from flask import request, jsonify

@app.route('/tasks', methods=['GET'])
def get_tasks():
    tasks = Task.query.all()
    return jsonify([task.to_dict() for task in tasks])

@app.route('/tasks', methods=['POST'])
def create_task():
    data = request.get_json()
    new_task = Task(
        title=data['title'],
        description=data.get('description'),
        owner_id=data['owner_id'],
        status=data.get('status', "non terminée")
    )
    db.session.add(new_task)
    db.session.commit()
    return jsonify(new_task.to_dict()), 201

@app.route('/tasks/<int:id>', methods=['GET'])
def get_task(id):
    task = Task.query.get_or_404(id)
    return jsonify(task.to_dict())

@app.route('/tasks/<int:id>', methods=['PUT'])
def update_task(id):
    data = request.get_json()
    task = Task.query.get_or_404(id)
    task.title = data['title']
    task.description = data.get('description')
    task.status = data.get('status', task.status)
    task.owner_id = data['owner_id']
    db.session.commit()
    return jsonify(task.to_dict())

@app.route('/tasks/<int:id>', methods=['DELETE'])
def delete_task(id):
    task = Task.query.get_or_404(id)
    db.session.delete(task)
    db.session.commit()
    return '', 204

2.6 Exemple de requête au serveur depuis le frontend

Exemple de composant React pour afficher une liste de tâches :

Javascript

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const TaskList = () => {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    axios.get('http://localhost:5000/tasks')
      .then(response => {
        setTasks(response.data);
      })
      .catch(error => {
        console.error('Il y avait une erreur lors de la récupération des tâches!', error);
      });
  }, []);

  return (
    <div>
      <h1>Liste des tâches</h1>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>{task.title} - {task.status}</li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION