Pourquoi Microservices avec Spring Boot ?
Dans un monde où les applications croissent en taille et en complexité, la modélisation monolithique devient rapidement inefficace et difficile à gérer. C'est là que l'architecture microservices entre en jeu. Un microservice est une unité autonome de code qui réalise une fonction spécifique. Avec Spring Boot, vous pouvez facilement créer des applications microservices réactives et performantes.
Un cas d'usage concret : imaginez une application bancaire où chaque service gère une fonctionnalité distincte comme l'enregistrement des transactions, la gestion des comptes ou la vérification de l'identité du client. Chaque service peut être développé, déployé et mis à jour indépendamment les uns des autres.
Prerequis
Pour suivre ce tutoriel, vous aurez besoin de :
- Java 11 ou plus récent
- Maven 3.x
- Docker (pour le déploiement)
- Un éditeur de code comme IntelliJ IDEA, Eclipse ou VSCode
Concepts fondamentaux
1. Projet Spring Boot
Un projet Spring Boot est une application autonome qui peut être démarrée avec un simple script java -jar. Voici comment créer un nouveau projet Spring Boot :
mvn archetype:generate -DgroupId=com.example -DartifactId=microservice-todo-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Cela créera un projet avec une structure de base :
microservice-todo-app/
├── pom.xml
└── src/
├── main/
│ ├── java/
│ │ └── com/example/microservicetodooapp/MicroserviceTodoAppApplication.java
│ └── resources/
│ └── application.properties
└── test/
└── java/
└── com/example/microservicetodooapp/MicroserviceTodoAppApplicationTests.java
2. Création d'un Service REST
Pour créer un service REST simple, vous pouvez utiliser la classe @RestController et l'annotation @RequestMapping.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/todos")
public class TodoController {
@GetMapping
public String getTodos() {
return "Liste des tâches";
}
}
3. Configuration de la Base de Données
Pour connecter votre service à une base de données, vous pouvez utiliser Spring Data JPA.
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface TodoRepository extends JpaRepository<Todo, Long> {
}
4. Gestion des Événements
Les événements sont cruciaux pour la communication entre microservices. Spring Cloud Stream permet de gérer les événements avec un modèle de prodconsommateur.
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
public interface TodoEventStream {
String OUTPUT = "todo-events";
@Output(OUTPUT)
MessageChannel todoEvents();
}
Mise en pratique : Projet Fil Rouge
Nous allons créer un gestionnaire de tâches simple avec Spring Boot. Le projet comprendra deux microservices :
microservice-todo-api: Un service REST qui expose des endpoints pour gérer les tâches.microservice-todo-service: Un service qui gère la logique métier et la communication entre le service API et la base de données.
Étape 1 : Création du Projet
Créez un nouveau projet Spring Boot avec Maven :
mvn archetype:generate -DgroupId=com.example -DartifactId=microservice-todo-api -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Étape 2 : Configuration du Service API
Ajoutez les dépendances nécessaires dans pom.xml :
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Étape 3 : Création du Modèle de Données
Créez une entité Todo :
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Todo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private boolean completed;
// Getters and Setters
}
Étape 4 : Création du Repository
Créez un repository JPA pour gérer les tâches :
import org.springframework.data.jpa.repository.JpaRepository;
public interface TodoRepository extends JpaRepository<Todo, Long> {
}
Étape 5 : Création du Controller
Créez un controller REST pour expposer des endpoints :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/todos")
public class TodoController {
@Autowired
private TodoRepository todoRepository;
@GetMapping
public List<Todo> getAllTodos() {
return todoRepository.findAll();
}
@PostMapping
public Todo createTodo(@RequestBody Todo todo) {
return todoRepository.save(todo);
}
}
Étape 6 : Configuration de la Base de Données
Ajoutez la configuration de la base de données dans application.properties :
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Étape 7 : Exécution du Service
Exécutez le service avec la commande suivante :
mvn spring-boot:run
Vous devriez pouvoir accéder aux endpoints de votre service API via http://localhost:8080/api/todos.
Erreurs Frequentes et Debugging
1. Problème d'Injection de Dépendance
Message d'erreur :
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'todoController': Unsatisfied dependency expressed through field 'todoRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'todoRepository': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: Unable to build Hibernate SessionFactory
Code incorrect :
@RestController
@RequestMapping("/api/todos")
public class TodoController {
@Autowired
private TodoRepository todoRepository;
// Endpoints
}
Code correct :
@RestController
@RequestMapping("/api/todos")
public class TodoController {
@Autowired
private TodoService todoService;
@GetMapping
public List<Todo> getAllTodos() {
return todoService.getAllTodos();
}
@PostMapping
public Todo createTodo(@RequestBody Todo todo) {
return todoService.createTodo(todo);
}
}
2. Problème de Configuration
Message d'erreur :
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Code incorrect :
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
Code correct :
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
3. Problème de Sérialisation
Message d'erreur :
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type `java.time.LocalDate` from String "01/01/2022": Failed to convert String to LocalDate
Code incorrect :
public class Todo {
private LocalDate dueDate;
}
Code correct :
import com.fasterxml.jackson.annotation.JsonFormat;
public class Todo {
@JsonFormat(pattern = "dd/MM/yyyy")
private LocalDate dueDate;
}
Pouraller plus loin
1. Sécurité avec Spring Security
Ajoutez Spring Security pour sécuriser votre service API :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Créez un fichier SecurityConfig.java pour configurer la sécurité.
2. Circuit Breaker avec Resilience4j
Ajoutez Resilience4j pour ajouter des resiliences à votre service :
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
</dependency>
Créez un fichier CircuitBreakerConfig.java pour configurer le circuit breaker.
3. Monitoring avec Micrometer
Ajoutez Micrometer pour monitorer votre service :
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
Créez un fichier MetricsConfig.java pour configurer la surveillance.
Défi Pratique
Développez un microservice pour gérer les utilisateurs. Créez un service REST pour créer, lire, mettre à jour et supprimer des utilisateurs. Utilisez Spring Data JPA pour la persistance des données dans une base de données H2 en mémoire.