Réalisation
Galactic Airlines
Conception d’une API REST avec Java Spring Boot autour d’un univers de gestion de vols.
Contexte
Dans le cadre du module Java Spring Boot de ma formation à l’ESIEA, un projet de groupe a été confié afin de mettre en pratique les concepts étudiés pendant le cours notamment en Design Pattern, c’est-à-dire des modèles de conception logiciels réutilisables permettant de résoudre des problèmes courants d’architecture et d’organisation du code.
L’objectif était de concevoir une application backend de gestion de réservations pour une compagnie aérienne fictive nommée Galactic Airlines.
Dans ce contexte, la compagnie devait disposer d’un système complet permettant de gérer les différents éléments nécessaires à l’organisation et à la réservation de vols : clients, employés, avions, aéroports, vols et réservations. Le système devait permettre la gestion de ces informations ainsi que la réservation de billets, que ce soit directement par les clients via un service en ligne ou par l’intermédiaire d’un agent en agence.
Pour accomplir le projet, j’ai été placé en binôme et le professeur serait le client lors du rendu final du projet pour valider nos compétences en Design Pattern et en gestion de projet.
Objectifs
Travailler sur le projet Galactic Airlines avait pour objectif principal de mettre en pratique les Design Patterns étudiés pendant le cours à travers la réalisation d’une application concrète. Il s’agissait notamment de démontrer notre capacité à utiliser ces modèles de conception afin de structurer le code de manière claire, modulaire et maintenable.
Au-delà de cet objectif pédagogique, le projet visait également à concevoir et développer une API REST avec Spring Boot permettant de gérer les différentes entités du système (clients, avions, aéroports, vols et réservations).
Enjeux et Risques
Enjeux
La réalisation du projet Galactic Airlines présentait plusieurs enjeux techniques et organisationnels. Le premier consistait à mettre correctement en pratique les Design Patterns étudiés pendant le cours. Il ne s’agissait pas seulement d’implémenter des fonctionnalités, mais également de structurer l’application de manière cohérente en appliquant des modèles de conception adaptés. Cela demandait une réflexion préalable sur l’architecture du projet afin d’éviter un code trop rigide.
Un autre enjeu important concernait la modélisation des données et des relations entre les entités du système. L’application devait gérer plusieurs objets métiers tels que les clients, les vols, les avions, les aéroports et les réservations. Il était donc nécessaire de concevoir un modèle de données cohérent permettant de représenter correctement les relations entre ces éléments tout en garantissant l’intégrité des informations.
Ce projet constituait aussi une étape d’évaluation du module Java Spring Boot, nécessaire à l’obtention de mon futur diplôme. La réussite du projet et de la présentation orale de ce dernier était donc essentielle pour valider les compétences attendues dans ce cours.
Risques
Risques
Plusieurs risques pouvaient également être identifiés lors de la réalisation du projet. Le premier concernait la gestion du temps, le projet devant être réalisé dans un délai limité avec une date de rendu imposée. Il était donc nécessaire d’organiser efficacement le travail afin de respecter cette échéance tout en assurant la qualité du développement.
Un autre risque concernait le choix d’utiliser une base de données non relationnelle. J’avais fait ce choix afin d’explorer une technologie différente des bases de données relationnelles que j’utilisais habituellement. Cependant, cette décision impliquait un temps d’apprentissage supplémentaire pour comprendre le fonctionnement des collections et adapter la modélisation des données à un modèle orienté documents.
Et enfin, sur l’utilisation des Design Patterns, vu que je devais démontrer ma maîtrise, le risque fût d’identifier correctement les situations dans lesquelles leur utilisation était pertinente.
Contexte humain
Le projet Galactic Airlines a été réalisé en binôme. Dans le cadre de ce projet, j’ai adopté une organisation en agilité avec ce dernier, afin de structurer le travail et d’avancer progressivement dans le développement de l’application.
Notre professeur jouait le rôle de client lors de la présentation finale du projet. Il nous a fourni le cahier des charges complet définissant les fonctionnalités attendues ainsi que les contraintes techniques à respecter. Cependant, durant la phase de développement, j’étais relativement autonome dans la gestion du projet et ne communiquais pas régulièrement avec le professeur pour le suivi.
L’organisation du travail reposait donc principalement sur mon binôme. Nous avons mis en place des échanges réguliers, discuté des choix techniques et réparti les différentes tâches à réaliser. Cette organisation nous a permis d’adopter une approche itérative du développement.
Etapes du projet
Étude du cahier des charges
La première étape du projet a consisté à analyser le cahier des charges remis par le professeur. Celui-ci présentait de manière claire l’ensemble des fonctionnalités attendues, les contraintes à respecter ainsi que les différentes entités métier à prendre en compte dans l’application. Le projet a été découpé en étapes cohérentes car les points énoncés dans l’intitulé du projet suivaient une logique progressive, ce qui m’a permis d’envisager un traitement des fonctionnalités dans l’ordre établi.
Enfin, j’ai défini notre répartition des tâches puis il a fallu se mettre en accord sur la stack technique à utiliser pour mener à bien le projet et enfin, j’ai préparé l’environnement de travail en créant le référentiel Git du projet.
Mise en place de l’environnement de développement
Afin de disposer d’une bonne base, le projet backend a été initialisé en utilisant Spring Initializer, un outil permettant de générer rapidement la structure d’un projet Spring Boot en sélectionnant les dépendances nécessaires (comme Spring Web pour la création d’API). Il a permis de bénéficier d’une structure de projet standard adaptée au développement d’une API REST, autrement dit une interface permettant de communiquer avec le serveur via des requêtes HTTP (GET, POST, PUT, DELETE) pour manipuler des données.
En parallèle, j’ai configuré la base de données MongoDB, en préparant les premières collections nécessaires au stockage des données.
Une attention particulière a été portée à l’organisation du projet, en mettant en place une arborescence claire des fichiers.
- Les contrôleurs, qui gèrent les requêtes entrantes et exposent les endpoints de l’API
- Les services, qui contiennent la logique métier de l’application
- Les modèles, qui représentent les données manipulées
- Ainsi que la couche d’accès aux données via les repositories
Cette organisation permet de faciliter la lisibilité du code, d’améliorer sa maintenabilité et de préparer l’intégration des Design Patterns.
L’architecture applicative
Une fois l’environnement établi, on est passé à la pratique, l’application fut agencée selon une architecture en couches reposant sur la séparation entre les modèles, les repositories, les services et les controllers.
Les modèles représentaient les entités métier comme les clients, les vols, les avions, les aéroports ou les réservations. Les repositories assuraient l’accès aux données. Les services regroupaient la logique métier , c’est-à-dire l’ensemble des règles et traitements qui définissent le fonctionnement de l’application (par exemple vérifier qu’un vol existe avant de créer une réservation). Les controllers exposaient les endpoints de l’API REST, ce sont des points d’accès permettant aux utilisateurs ou à d’autres applications d’interagir avec le système via des requêtes (comme consulter des vols ou créer une réservation).
Modélisation des entités métier
J’ai procédé à la modélisation des entités métier en me basant sur les éléments fournis dans le cahier des charges.
L’application reposait sur plusieurs entités principales représentant les différents éléments du système de réservation aérienne. Chacune de ces entités a été modélisée sous forme de classes, contenant les attributs nécessaires à leur description.
Les relations entre ces entités constituaient un point central du développement, notamment entre réservations, vols et clients. Par exemple, une réservation est liée à un vol et à un client, ce qui implique de vérifier la cohérence des données lors de sa création. De même, un vol est associé à un avion ainsi qu’à des aéroports de départ et d’arrivée, ce qui permet de représenter de manière réaliste le fonctionnement d’un système de transport aérien.
Développement des fonctionnalités
Pour commencer, j’ai implémenté des opérations CRUD (Create, Read, Update, Delete) pour les différentes entités métier du projet. Ces opérations permettent de créer, consulter, modifier et supprimer les données via les endpoints de l’API REST.
Dans un second temps, le système de réservation a été développé, lui qui constitue le cœur fonctionnel de l’application. Celui-ci permet d’associer un client à un vol, en prenant en compte les informations nécessaires à la création d’une réservation.
Des règles de gestion ont été intégrées directement dans les services afin de garantir la validité des opérations effectuées. Cela permet de contrôler les données manipulées et d’assurer un comportement cohérent de l’application.
L’ensemble des fonctionnalités développées a ainsi permis de couvrir les besoins définis dans le cahier des charges, tout en s’appuyant sur notre organisation prédéfinie.
Sécurité
Afin de sécuriser l’accès à l’application, un mécanisme d’authentification basé sur OAuth2 a été mis en place. Ce protocole permet de contrôler l’accès aux différentes ressources de l’API en s’assurant que seules les requêtes authentifiées peuvent accéder à certaines fonctionnalités.
L’intégration de la sécurité a nécessité la configuration de filtres et de règles d’accès au sein de l’application, afin de protéger les endpoints sensibles et de limiter les actions possibles selon le niveau d’autorisation.
Grâce à cette intégration, une couche de sécurité essentielle a été introduite dans une application exposant des données, tout en me familiarisant avec les problématiques liées à l’authentification et à la gestion des accès.
Contexte technique
Afin de couvrir les différents aspects du développement d’une application backend, nous avons utilisé diverses technologies.
Spring Boot
Le développement a été réalisé avec Spring Boot, un framework Java facilitant la création d’applications backend grâce à sa configuration simplifiée et à son écosystème riche.
Spring Initializer a été utilisé pour générer le projet et sélectionner les dépendances nécessaires, notamment Spring Web, qui permet de développer des API REST en exposant des endpoints accessibles via des requêtes HTTP. Cette dépendance nous a permis de mettre en place facilement les controllers et de gérer les différentes routes de l’application.
Spring Boot permet également de structurer notre projet selon une architecture claire, en s’appuyant sur ses conventions. L’utilisation des annotations (comme @RestController, @Service ou @Repository) a facilité la séparation des responsabilités au sein de l’application et la mise en place des différentes couches.
MongoDB
La gestion des données a été assurée par MongoDB, une base de données NoSQL orientée documents. Contrairement aux bases de données relationnelles traditionnelles, les données y sont stockées sous forme de documents JSON, ce qui offre une plus grande flexibilité dans la structuration des informations.
Ce choix s’inscrivait dans une volonté de découvrir une technologie différente de celles habituellement utilisées dans notre formation. Il amène à adapter la manière de modéliser les données, notamment dans la gestion des relations entre entités du système.
MongoDB s’intègre naturellement avec Spring Boot grâce à l’utilisation de la dépendance Spring Data, qui permet de manipuler les données via des interfaces de repository sans avoir à écrire de requêtes complexes, facilitant ainsi l’implémentation des opérations de persistance tout en conservant une bonne lisibilité du code.
Docker et Jenkins
Docker a été utilisé pour déployer un environnement Jenkins au sein de l’application. Grâce à un fichier docker-compose.yml, j’ai pu lancer une instance Jenkins sans avoir à l’installer manuellement sur ma machine.
Jenkins a permis d’introduire une première approche de l’intégration continue, en automatisant l’exécution des tests de l’application. Cette automatisation vérifie le bon fonctionnement du projet de manière régulière et détecte d’éventuelles erreurs plus rapidement.
L’utilisation de Docker dans ce contexte a simplifié la mise en place de Jenkins et a garanti un environnement stable et reproductible. J’ai pu découvrir des pratiques utilisées en entreprise pour automatiser et fiabiliser le cycle de développement.
Outils de test et documentation (Postman & Swagger)
En l’absence d’interface utilisateur, j’ai utilisé Postman afin de tester les différentes routes de l’API. Cet outil permet d’envoyer des requêtes HTTP et de vérifier les réponses du serveur, ce qui facilite la validation du bon fonctionnement des fonctionnalités développées.
En complément, Swagger fut intégré, un outil permettant de générer automatiquement une documentation interactive de l’API. Il offre une interface web dans laquelle il est possible de visualiser les endpoints disponibles, leurs paramètres ainsi que de tester directement les différentes requêtes.
Grâce à cette interface, il est également possible de tester les mécanismes de sécurité mis en place, notamment l’authentification OAuth2, ce qui permet de vérifier le bon fonctionnement des accès sécurisés.
L’utilisation combinée de ces outils donne la possibilité de tester efficacement l’application tout au long du développement, tout en disposant d’une documentation claire et accessible.
Logs (Log4j)
Afin de faciliter le suivi et le diagnostic du comportement de l’application, j’ai mis en place un système de journalisation avec Log4j. Cet outil permet d’enregistrer des informations sur l’exécution du programme, comme les actions effectuées, les événements importants ou encore les erreurs rencontrées.
L’intégration des logs permet de mieux comprendre le déroulement des opérations au sein de l’application, notamment lors des phases de développement et de test. En cas de problème, ils constituent une aide précieuse pour identifier l’origine des erreurs et corriger plus rapidement les anomalies.
Cette mise en place contribue également à améliorer la maintenabilité de l’application, en offrant une meilleure visibilité sur son fonctionnement.
Technologies utilisées
Résultats, Analyse et Perspectives
L’objectif principal de ce projet était de mettre en pratique les Design Patterns en Java, ainsi que de maîtriser la conception d’API REST avec Spring Boot. La réalisation du projet, ainsi que la présentation finale accompagnée de tests via Swagger et Postman, se sont déroulées avec succès et ont abouti sur la validation du module Java Spring Boot.
Ce projet s’est révélé particulièrement enrichissant, car il regroupait plusieurs notions essentielles du développement backend. J’ai eu l’occasion de consolider mes compétences en programmation orientée objet, en conception d’API, ainsi qu’en organisation de projet. Le travail en binôme et la simulation d’un contexte professionnel avec un client ont également contribué à renforcer ma capacité à structurer un projet de bout en bout.
Sur le plan technique, j’ai pu appliquer de bonnes pratiques de développement, mettre en place une architecture claire et maintenable, et expérimenter l’utilisation d’une base de données NoSQL avec MongoDB. L’intégration d’outils comme Docker, Jenkins, Swagger ou encore Log4j a fortement aidé à avoir une vision complète d’un environnement de développement moderne.
En termes de perspectives d’amélioration, il serait intéressant d’aller plus loin dans l’utilisation de Docker, en conteneurisant l’ensemble des services de l’application et pas uniquement certains outils, afin d’obtenir un environnement totalement isolé et reproductible. De plus, l’ajout d’une interface utilisateur (frontend) permettrait de rendre l’application plus complète et d’améliorer l’expérience utilisateur.