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 nous 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 Galactics Airlines.

Dans ce contexte, la compagnie devait disposer d’un système 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 réussir notre tâche, nous avons été répartis en binôme et notre professeur était le « client » lors du rendu final du projet pour valider nos compétences en Design Pattern et en matière de gestion de projet.

Objectifs

Travailler sur le projet Galactics 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 Galactics Airlines présentait plusieurs enjeux techniques et organisationnels. Le premier enjeu 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 différentes 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 notre futur diplôme. La réussite du projet et de la présentation orale de ce dernier était donc essentielles pour valider les compétences attendues dans ce cours.

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. Ce choix avait été fait par notre binôme afin d’explorer une technologie différente des bases de données relationnelles que nous utilisions habituellement. Cependant, cette décision impliquait un temps d’apprentissage supplémentaire, notamment pour comprendre le fonctionnement des collections et adapter la modélisation des données à un modèle orienté documents.

Enfin, sur l’utilisation des Design Patterns, vu que nous devions démontrer notre maîtrise, le risque fût d’identifier correctement les situations dans lesquelles leur utilisation était pertinente.

Contexte humain

Le projet Galactics Airlines a été réalisé en binôme. Dans le cadre de ce projet, nous avons adopté une organisation en agilité, afin de structurer notre 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, nous étions relativement autonomes dans la gestion du projet et ne communiquions pas régulièrement avec lui pour le suivi.

L’organisation du travail reposait donc principalement sur notre binôme. Nous avons mis en place des échanges réguliers, discuter des choix techniques et répartir les différentes tâches à réaliser. Elle nous a permis d’adopter une approche itérative du développement.

Etapes du projet

Etude 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. On a alors pu découper le projet en étapes cohérentes, sans nous disperser car les points énoncés dans l’intitulé du projet suivaient une logique progressive, ce qui nous a permis d’envisager un traitement des fonctionnalités dans l’ordre établi.

Enfin, nous avons défini notre répartition des tâches, nous nous sommes mis en accord sur la stack technique à utiliser pour mener à bien le projet et nous avons 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, nous avons initialisé le projet backend 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). Cela nous 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, nous avons configuré la base de données MongoDB, en préparant les premières collections nécessaires au stockage des données.

Nous avons également porté une attention particulière à l’organisation du projet, en mettant en place une arborescence claire des fichiers. Cette arborescence visait à séparer les différentes responsabilités de l’application :

  1. Les contrôleurs, qui gèrent les requêtes entrantes et exposent les endpoints de l’API ;
  2. Les services, qui contiennent la logique métier de l’application ;
  3. Les modèles, qui représentent les données manipulées ;
  4. 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 qui reposait notamment sur la séparation entre les modèles, les repositories, les services et les controllers.

Les modèles permettaient de représenter les différentes entités métier du projet, comme les clients, les vols, les avions, les aéroports ou les réservations. Les repositories assuraient l’accès aux données stockées dans MongoDB. 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). Enfin, les controllers exposaient les différents 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

Nous avons procédé à la modélisation des entités métier en nous basant sur les éléments fournis dans le cahier des charges.

L’application repose 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. 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, nous avons implémenté les 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, nous avons développé le système de réservation, 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.

Nous avons également intégré des règles de gestion 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, nous avons mis en place un mécanisme d’authentification basé sur OAuth2. 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.

Nous avons pu introduire grâce à cette intégration une couche de sécurité essentielle dans une application exposant des données, tout en nous 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.

SpringBoot

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.

Nous avons utilisé Spring Initializer 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 nous a également permis 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 nous a amenés à adapter notre manière de modéliser les données, notamment dans la gestion des relations entre les différentes 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. Cela a facilité 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, nous avons pu lancer une instance Jenkins sans avoir à l’installer manuellement sur notre machine.

Jenkins nous 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 permet de vérifier le bon fonctionnement du projet de manière régulière et de détecter d’éventuelles erreurs plus rapidement.

L’utilisation de Docker dans ce contexte nous a permis de simplifier la mise en place de Jenkins et de garantir un environnement stable et reproductible. Cela nous a également permis de 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, nous avons 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 retournées par le serveur, ce qui facilite la validation du bon fonctionnement des fonctionnalités développées.

En complément, nous avons intégré Swagger, 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 via OAuth2, ce qui permet de vérifier le bon fonctionnement des accès sécurisés.

L’utilisation combinée de ces outils nous a permis 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, nous avons 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 nous a permis de mieux comprendre le déroulement des différentes 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

JavaSpring BootMongoDBDockerSwagger

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 nous ont permis de valider le module Java Spring Boot.

Ce projet s’est révélé particulièrement enrichissant, car il regroupait plusieurs notions essentielles du développement backend. Il nous a permis de consolider nos 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 notre capacité à structurer un projet de bout en bout.

Sur le plan technique, nous avons pu appliquer des 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 nous a également permis d’avoir une vision plus 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.