
Structurer, connecter et sécuriser des microservices avec Spring Boot – un guide pratique complet avec des exemples de code réels et des diagrammes d'architecture.
Qu'est-ce que les microservices ?
Une architecture microservices décompose une application en petits services déployables indépendamment. Chaque service est responsable d'exactement un domaine métier – le Bounded Context issu du Domain-Driven Design.

Chaque service dispose de sa propre base de données – cela évite le couplage fort et permet à chaque service de choisir son propre type de base de données.
Structure du projet
order-service/
├── src/main/java/com/zelkulon/order/
│ ├── OrderServiceApplication.java
│ ├── controller/
│ │ └── OrderController.java
│ ├── service/
│ │ ├── OrderService.java
│ │ └── OrderServiceImpl.java
│ ├── repository/
│ │ └── OrderRepository.java
│ ├── model/
│ │ ├── Order.java
│ │ └── OrderItem.java
│ └── dto/
│ ├── OrderRequest.java
│ └── OrderResponse.java
└── src/main/resources/
└── application.ymlLe modèle de domaine
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
private String customerId;
@Enumerated(EnumType.STRING)
private OrderStatus status;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<OrderItem> items = new ArrayList<>();
private BigDecimal totalAmount;
@PrePersist
void onCreate() {
this.createdAt = LocalDateTime.now();
this.status = OrderStatus.PENDING;
}
}Communication entre services avec Feign
Avec Spring Cloud OpenFeign, un autre microservice se comporte comme un objet de service local :
@FeignClient(name = "product-service", url = "${services.product.url}")
public interface ProductServiceClient {
@GetMapping("/api/products/{productId}")
ProductDto getProduct(@PathVariable String productId);
@PutMapping("/api/products/{productId}/stock")
void reduceStock(@PathVariable String productId,
@RequestParam int quantity);
}Circuit Breaker avec Resilience4j
Les Circuit Breakers préviennent les pannes en cascade lorsqu'un service est inaccessible :
@Service
public class OrderServiceImpl implements OrderService {
@Override
public OrderResponse placeOrder(OrderRequest request) {
CircuitBreaker cb = circuitBreakerFactory.create("product-service");
boolean available = cb.run(
() -> checkProductAvailability(request.getItems()),
throwable -> {
log.warn("ProductService inaccessible – fallback actif");
return false;
}
);
if (!available) throw new OrderException("Produits indisponibles");
return processOrder(request);
}
}Pattern Saga pour les transactions distribuées
Dans les microservices, il n'y a pas de transactions de base de données globales. Le Pattern Saga résout ce problème :

Conclusion
- Un service = un domaine métier – pas de services dieu
- Base de données propre par service empêche le couplage des données
- Les Circuit Breakers sont indispensables pour les systèmes prêts pour la production
- L'API Gateway centralise l'authentification et le routage
- Le Pattern Saga résout le problème des transactions distribuées