Exemple Spring MicroService Spring Boot : Les problématiques rencontrées par les entreprises

  • Problème n°1 : comment faire en sorte que les applications proposées en ligne soient toujours disponibles et ne souffrent jamais de coupure ou de ralentissement, quelle que soit l’affluence des utilisateurs sur celles-ci ?
  • Problème n°2 : les entreprises se livrent à une “guerre de la mise à jour“. Il faut que l’entreprise soit capable de faire évoluer son application de façon très fréquente et de répondre rapidement aux nouvelles fonctionnalités que propose la concurrence.
  • Problème n°3 : Les technologies utilisées pour développer ces applications évoluent très vite et les nouveautés offrent parfois des avantages énormes. Comment les entreprises peuvent-elle  s’adapter rapidement pour tirer profit de ces évolutions .

Solution Proposé : les MicroService

Lire avant : Création Projet Spring Boot
Exemple Spring MicroService Spring Boot : Les microservices sont une technique de développement logiciel qui respecte l’architecture orientée services et qui structure une application comme un ensemble de services faiblement couplés.

Des API REST sont souvent employées pour relier chaque microservice aux autres. Dans le cas d’un besoin critique de mise a jour d’une resource, seul le microservice contenant cette resource sera mise a jour.

Architecture des MicroServices :

L’architecture Microservices propose une solution simple et efficace.

Cette solution consiste a découper une application en petits services, appelés Microservices,  parfaitement autonomes qui exposent une API REST que les autres Microservices pourront consommer. 

  • Chaque Microservice est parfaitement autonome : il a sa propre base de données, son propre serveur d’application (tomcat, jetty, etc.), ses propres librairies et ainsi de suite. La plupart du temps ces Microservices sont chacun dans un container Docker, ils sont donc totalement indépendants y compris vis-à-vis de la machine sur laquelle ils tournent.
  • Voici une vue plus détaillée sur l’architecture MicroService:

  • Quand on voudra mettre à jour l’application, il suffira de cibler directement le Microservice responsable de la fonctionnalité en question.

Créez un MicroService grâce a Spring Boot 

  • Spring Initializr :

Pour débuter, rendez-vous sur https://start.spring.io. Cliquez sur “Switch to the full version” :

Plateforme Spring Initializr
Plateforme Spring Initializr
  • Vous verrez apparaitre, en bas, tous les starters et ensembles de dépendances pour les cas d’usage les plus courants. Cela va du starter web, que nous avons vu dans le chapitre précédent, aux bases de données, en passant par les moteurs de template, la sécurité, le messaging, ainsi que d’autres outils très importants dans une architecture Microservices, que nous verrons plus tard.
  • Nous allons, dans les prochains chapitres, développer un mini-système d’e-commerce fondé sur l’architecture Microservices avec Spring Boot. Nous allons commencer par un premier Microservice qui gère les produits que nous allons proposer à la vente. Il doit pouvoir ajouter, supprimer, mettre à jour et afficher les produits.
  • Dans une première étape, nous allons créer une version très simplifiée de ce Microservice. Nous enrichirons ce Microservice au fur et à mesure de notre découverte des différents concepts à assimiler.

Retournez sur Spring Initializr et renseignez les Metadata du projet comme suit:

Group :  com.ecommerce  

Artifact :  microcommerce  

Name :  microcommerce  

Packaging :  jar  

Java Version :  8  

La figure suivante vous présente le formulaire renseigné avec ces informations:

  • Pom.xml

Comme nous l’avons vu dans le chapitre précédent, ce pom.xml hérite du parent spring-boot-starter-parent qui nous permet de ne plus nous soucier des versions des dépendances et de leur compatibilité :

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.9.RELEASE</version>

<relativePath/> <!– lookup parent from repository –>

</parent>

Vous avez la possibilité de choisir la version de Java à utiliser. Comme nous avons sélectionné Java 8 dans l’interface de Spring Initializr, une balise XML <java.version> a été ajoutée dans la partie properties du fichier pom.xml, comme nous pouvons le voir dans le code qui suit :

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF8</project.reporting.outputEncodin>

<java.version>1.8</java.version>

</properties>

Le pom.xml définit ensuite une dépendance vers le starter qui va ajouter à notre Microservice toutes les dépendances de base nécessaires pour démarrer rapidement :

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

Pour voir la liste des dépendances importées, rendez-vous à gauche dans « External  Libraries ». Vous avez dans cette liste principalement :

  • Jackson : permet de parser JSON et faire le lien entre les classes Java et le contenu JSON.
  • Tomcat : intégré, va nous permettre de lancer notre application en exécutant tout simplement le jar sans avoir à le déployer dans un serveur d’application.
  • Hibernate : facilite la gestion des données.
  • MicrocommerceApplication.java

Cette classe, générée automatiquement par Spring Boot, est le point de démarrage de l’application :

@SpringBootApplication

public class MicrocommerceApplication {

public static void main(String[] args) {

SpringApplication.run(MicrocommerceApplication.class, args);

}

}

Elle lance, entre autres, la classe SpringApplication, responsable du démarrage de l’application Spring. Cette classe va créer le fameux « ApplicationContext » dans lequel iront toutes les configurations générées automatiquement ou ajoutées par vos soins.

Mais le plus important ici, c’est bien sûr l’annotation @SpringBootApplication, qui est une simple encapsulation de trois annotations :

  • @Configuration : donne à la classe actuelle la possibilité de définir des configurations qui iront remplacer les traditionnels fichiers XML. Ces configurations se font via des Beans.
  • @EnableAutoConfiguration : l’annotation vue précédemment qui permet, au démarrage de Spring, de générer automatiquement les configurations nécessaires en fonction des dépendances situées dans notre classpath.
  • @ComponentScan : Indique qu’il faut scanner les classes de ce package afin de trouver des Beans de configuration.

Nous reviendrons sur la configuration dans une prochaine section. Si vous souhaitez personnaliser finement le comportement de Spring Boot, il vous suffit de remplacer @SpringBootApplication par ces 3 annotations. 

@Configuration

@EnableAutoConfiguration

@ComponentScan

public class MicrocommerceApplication { }

Cette modification permet notamment de paramétrer l’annotation @ComponentScan, par exemple pour cibler des fichiers à scanner.

  • Application.properties

Ce fichier va vous permettre de modifier très simplement un nombre impressionnant de configurations liées à Spring Boot et ses dépendances. Par exemple : changer le port d’écoute de Tomcat, l’emplacement des fichiers de log, les paramètres d’envoi d’emails..

  • Nous n’avons rien ajouté dans notre application pour l’instant, mais nous pouvons déjà l’exécuter.
    Run as Maven Install
    L’application sera compilée et vous retrouverez le jar sous le nouveau dossier « Target » créé pour l’occasion par Maven

Exécutez enfin l’application depuis un terminal comme n’importe quel jar grâce à la commande :

java -jar Chemin/vers/microcommerce/target/microcommerce-0.0.1-SNAPSHOT.jar

Vous devriez alors avoir un retour de ce type :

Figure 4: Execution

Dans les dernières lignes vous remarquerez cette phrase : «  Tomcat started on port(s): 8080 (http) » Ce qui vous indique que votre application tourne et qu’elle est en écoute grâce à tomcat sur le port 8080.

Et bien, rendez-vous dans votre navigateur à l’adresse http://localhost:8080. Vous obtenez alors cette magnifique erreur, car nous n’avons encore pas fourni d’éléments  à afficher !

Vous pouvez en profiter pour essayer la personnalisation de l’auto-configuration de Spring Boot via application.properties.

Changeons par exemple le port du serveur. Ajoutez tout simplement cette ligne :

server.port = 9090

Exécutez maintenant l’application. Spring vous indique alors que l’application tourne désormais sur le port 9090 

  1. Créer l’API REST

Nous arrivons maintenant au coeur du Microservice que nous voulons développer. Ce Microservice va devoir être RESTful et donc pouvoir communiquer de cette manière.

  • Quels sont les besoins ?

Nous avons besoin d’un Microservice capable de gérer les produits. Pour cela, il doit pouvoir exposer une API REST qui propose toutes les opérations CRUD (Create, Read, Update, Delete).

  • Nous allons donc avoir :

Une classe Produit qui représente les caractéristiques d’un produit (nom, prix, etc.)

Un contrôleur qui s’occupera de répondre aux requêtes CRUD et de faire les opérations nécessaires.

Nous voulons donc pouvoir appeler notre Microservice sur les URLs suivantes :

  • Requête GET à /Produits : affiche la liste de tous les produits.
  • Requête GET à /Produits/{id} : affiche un produit par son Id.
  • Requête PUT à /Produits/{id} : met à jour un produit par son Id.
  • Requête POST à /Produits : ajoute un produit.
  • Requête DELETE à /Produits/{id} : supprime un produit par son Id.
  • Créez le controleur REST : ProductController.java

Nous allons commencer par indiquer à Spring que ce contrôleur est un contrôleur REST a travers l’annotation @RestController. Saisissez le code suivant dans la classe « ProductController »

package com.ecommerce.microcommerce.web.controller;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class ProductController { }

  • Méthode pour GET /Produits:

@RestController

public class ProductController {

@RequestMapping( value=”/Produits” , method = RequestMethod.GET )

public String listeProduits( ) {

return “Un exemple de produit”;

}

}

  • L’annotation @RequestMapping : permet de faire le lien entre l’URL “/Produits”, invoquée via GET, et la méthode « listeProduits » .
  • L’annotation @RequestMapping :Cette annotation accepte plusieurs paramètres , dont voici les principaux :
  • value : C’est ici que vous indiquez l’URI à laquelle cette méthode doit répondre. Vous pouvez également indiquer des paramètres, nous y reviendrons.
  • method : Vous indiquez ici à quel type de requêtes cette méthode doit répondre. Dans notre cas, notre méthode listeProduits ne sera déclenchée que si l’URI est exactement “/Produits” et que la requête est de type GET. Si vous appelez “/Produits” avec un POST, notre méthode ne sera tout simplement pas évoquée. methodaccepte toutes les requêtes CRUD.
  • produces : Dans certains cas d’utilisations avancées, vous aurez besoin de préciser, par exemple, que votre méthode est capable de répondre en XML et en JSON. Cela entre aussi dans le choix de la méthode qui correspond le mieux à la requête. Si la requête contient du XML et que vous avez 2 méthodes identiques, dont une capable de produire du XML, c’est celle-ci qui sera appelée. Il en va de même pour consumes qui précise les formats acceptés. Dans la plupart des cas, vous n’avez pas besoin de renseigner ces paramètres.
  • Il ne reste plus qu’à lancer l’application et se rendre à http://localhost:9090/Produits.
  • Méthode pour GET /Produits/{id}:

Créons maintenant une autre méthode capable d’accepter un Id de produit en paramètre :

@GetMapping(value=”/Produits/{id}”)

public Product afficherUnProduit(@PathVariable int id) {

Product product=newProduct(id, new String(“Aspirateur”), 100 );

return product; }

  • Créez le DAO : ProductDao.java

Nous allons nous rapprocher un peu plus d’un cas d’utilisation réel en créant la DAO nécessaire pour communiquer avec une base de données. Nous allons simuler celle-ci grâce à des données statiques.

Créez un package et nommez-le dao puis créez dedans une interface nommée ProductDao, dans laquelle vous allez déclarer les opérations que nous allons implémenter. 

package com.ecommerce.microcommerce.dao;

import com.ecommerce.microcommerce.model.Product;

import java.util.List;

public interface ProductDao {

public List<Product> findAll( );

public Product findById(int id);

public Product save(Product product);

}

Maintenant que notre interface est prête, nous allons pouvoir créer son implémentation. Créez une classe ProductDaoImpl qui implémente l’interface que nous venons de créer. 

public class ProductDaoImpl implements ProductDao {

@Override

public List<Product> findAll() {

return null;

}

@Override

public Product findById(int id) {

return null;

}

@Override

public Product save(Product product) {

return null;

}

}

Normalement , cette classe est censée communiquer avec la base de données pour récupérer les produits ou en ajouter. Nous allons simuler ce comportement en créant des Produits en dur dans le code.

@Repository

public class ProductDaoImpl implements ProductDao {

public static List<Product> products = newArrayList <> ( );

static {

products.add(newProduct(1, newString(“Ordinateur portable”), 350));

products.add(newProduct(2, newString(“Aspirateur Robot”), 500));

products.add(newProduct(3, newString(“Table de Ping Pong”), 750));

}

@Override

public List<Product>findAll( ) {

return products;

}

@Override

public ProductfindById ( int id ) {

for (Product product : products) {

if(product.getId() ==id){

return product;

}

}

return null;

}

@Override

public Product save( Product product ) {

products.add(product);

return product;

}

}

  • @Repository : cette annotation est appliquée à la classe afin d’indiquer à Spring qu’il s’agit d’une classe qui gère les données, ce qui nous permettra de profiter de certaines fonctionnalités comme les translations des erreurs. Nous y reviendrons.
  • Interagir avec les données

Nous allons maintenant modifier notre contrôleur afin qu’elle utilise notre couche DAO pour manipuler les produits.

@RestController

public class ProductController {

@Autowired

private Product DaoproductDao;

// Récupérer la liste des produits

@RequestMapping(value = “/Produits”, method=RequestMethod.GET)

public List<Product> listeProduits( ) {

return productDao.findAll();

}

// Récupérer un produit par son Id

@GetMapping(value=”/Produits/{id}”)

public Product afficherUnProduit(@PathVariable int id) {

return productDao.findById(id);

}

}

Source : Spring.io

Laisser un commentaire