Skip to Content
01 FundamentalsGuide des Annotations

Guide des Annotations

Guide complet des annotations Lombok et Micronaut utilisées dans l’architecture hexagonale.

Ce guide explique toutes les annotations utilisées dans le projet avec des exemples concrets et du code généré automatiquement.

Pourquoi ce guide ?

Comprendre ces annotations est essentiel pour :

  • Réduire le boilerplate : Lombok génère automatiquement getters, setters, constructeurs…
  • Maîtriser l’injection de dépendances : Micronaut gère les dépendances avec @Singleton
  • Créer des APIs REST : Controllers et mapping HTTP simplifiés
  • Écrire du code propre : Moins de code = plus de lisibilité

Annotations Lombok

Lombok génère du code automatiquement pour éviter le boilerplate. Toutes ces annotations fonctionnent à la compilation.

@RequiredArgsConstructor

Crée un constructeur avec tous les champs final ou @NonNull.

@RequiredArgsConstructor public class GetTrendsUseCase { private final TrendRepository trendRepository; private final Logger logger; }

Quand l’utiliser : Pour l’injection de dépendances dans vos use cases, controllers, repositories.


@AllArgsConstructor

Crée un constructeur avec TOUS les champs (pas seulement les final).

@AllArgsConstructor public class User { private String name; private int age; private String email; }

Moins utilisé que @RequiredArgsConstructor. Préférez @Value pour les classes immutables.


@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)

Modifie automatiquement les modificateurs de tous les champs de la classe.

Options :

  • level = AccessLevel.PRIVATE → Tous les champs deviennent private
  • makeFinal = true → Tous les champs deviennent final
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class TrendController { GetTrendsUseCase getTrendsUseCase; }

Évite de répéter private final devant chaque champ. Parfait en combinaison avec @RequiredArgsConstructor.


@Value

Crée une classe immutable (non modifiable) en une seule annotation.

Équivalent à :

  • @AllArgsConstructor
  • @Getter (tous les champs)
  • @FieldDefaults(level = PRIVATE, makeFinal = true)
  • @ToString
  • @EqualsAndHashCode
@Value public class TrendQuery { String keyword; String region; LocalDateTime timestamp; }

Idéal pour :

  • DTOs (Data Transfer Objects)
  • Entités du domain
  • Value Objects
  • Toute classe qui ne doit jamais changer une fois créée

Annotations Micronaut

Micronaut gère l’injection de dépendances et le cycle de vie des beans avec ces annotations.

@Singleton

Dit à Micronaut de créer une seule instance de cette classe et de la réutiliser partout.

@Singleton public class GetTrendsUseCase { // Une seule instance partagée dans toute l'application }

Comportement :

GetTrendsUseCase instance1 = context.getBean(GetTrendsUseCase.class); GetTrendsUseCase instance2 = context.getBean(GetTrendsUseCase.class); // instance1 == instance2 → TRUE (même objet réutilisé!)

Quand l’utiliser :

  • Use cases
  • Services métier
  • Repositories
  • Tout ce qui n’a pas d’état mutable (pas de champs modifiables)

Évitez les champs mutables dans un @Singleton car ils seraient partagés entre toutes les requêtes!


@Controller("/api/trends")

Marque la classe comme un contrôleur REST et définit le chemin de base des endpoints.

@Controller("/api/trends") public class TrendController { @Get // GET http://localhost:8080/api/trends public String list() { ... } @Get("/{id}") // GET http://localhost:8080/api/trends/123 public String getById(String id) { ... } @Post // POST http://localhost:8080/api/trends public String create() { ... } }

Le chemin spécifié dans @Controller est préfixé à tous les endpoints de la classe.


@Get, @Post, @Put, @Delete

Définissent le verbe HTTP de l’endpoint (CRUD operations).

@Controller("/users") public class UserController { @Get // GET /users public List<User> list() { ... } @Get("/{id}") // GET /users/123 public User getById(Long id) { ... } @Post // POST /users public User create(@Body User user) { ... } @Put("/{id}") // PUT /users/123 public User update(Long id, @Body User user) { ... } @Delete("/{id}") // DELETE /users/123 public void delete(Long id) { ... } }

Convention REST :

  • @Get → Lecture (SELECT)
  • @Post → Création (INSERT)
  • @Put → Mise à jour complète (UPDATE)
  • @Delete → Suppression (DELETE)

@QueryValue

Récupère un paramètre de query string dans l’URL (?key=value).

@Get public String search( @QueryValue String keyword, // Obligatoire @QueryValue(defaultValue = "US") String region // Optionnel avec défaut ) { return "Searching for " + keyword + " in " + region; }
GET http://localhost:8080/api/trends?keyword=java&region=FR

Variables :

  • keyword = "java"
  • region = "FR"

Utilisations courantes :

  • Filtres (?category=tech&status=active)
  • Recherche (?q=micronaut)
  • Pagination (?page=2&size=20)
  • Tri (?sort=createdAt&order=desc)

@PathVariable (ou juste le nom du paramètre)

Récupère une variable du chemin (path parameter).

@Get("/{id}") public User getById(Long id) { // id vient automatiquement du chemin return userRepository.findById(id); }

Requête :

GET http://localhost:8080/users/123

Résultat : id = 123

Dans Micronaut, pas besoin de @PathVariable explicite si le nom du paramètre correspond au placeholder !

Cas d’usage :

  • Identifiant de ressource (/users/123)
  • Slug d’article (/posts/my-article)
  • Catégorie (/products/electronics)

@Body

Récupère le corps de la requête HTTP et le transforme automatiquement en objet Java.

@Post public User create(@Body User user) { // user est automatiquement créé à partir du JSON reçu return userService.save(user); }

Requête :

POST http://localhost:8080/users Content-Type: application/json { "name": "Alice", "email": "alice@example.com" }

Résultat dans le code :

user.getName() // "Alice" user.getEmail() // "alice@example.com"

Micronaut utilise Jackson pour la désérialisation JSON → Java automatiquement.

Quand l’utiliser :

  • @Post → Créer une ressource
  • @Put → Remplacer complètement
  • @Patch → Modifier partiellement

Comparaison Query vs Path vs Body

Voici quand utiliser chaque type de paramètre dans vos endpoints REST.

TypeAnnotationExempleCas d’usage
Query String@QueryValue/users?name=alice&age=25Filtres, recherche, pagination, options
Path VariableAucune (auto)/users/123Identifiant unique de ressource
Request Body@BodyPOST/PUT avec JSONCréer/modifier des données complexes
// Filtrer une liste @Get public List<User> search( @QueryValue(required = false) String name, @QueryValue(defaultValue = "0") int page ) { ... } // GET /users?name=alice&page=2

Exemple Complet Commenté

@RequiredArgsConstructor // Génère le constructeur avec trendRepository @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) // Tous les champs → private final @Controller("/api/trends") // Contrôleur REST sur /api/trends public class TrendController { GetTrendsUseCase getTrendsUseCase; // Devient: private final GetTrendsUseCase getTrendsUseCase // Endpoint: GET http://localhost:8080/api/trends?keyword=java&region=FR @Get // Verbe HTTP GET public TrendResponseDto getTrends( @QueryValue String keyword, // Query param obligatoire @QueryValue(defaultValue = "US") String region // Query param avec défaut ) { return getTrendsUseCase.execute(keyword, region) .map(TrendResponseDto::fromDomain) .orElseThrow(() -> new RuntimeException("Unable to fetch trends")); } }

Résumé Rapide

Tableau de référence rapide pour toutes les annotations du projet.

AnnotationTypeRésuméExemple
@RequiredArgsConstructorLombokConstructeur champs finalUse cases, services
@AllArgsConstructorLombokConstructeur tous champsMoins utilisé
@FieldDefaultsLombokModifier champs automatiquementÉvite private final
@ValueLombokClasse immutable complèteDTOs, Value Objects
@SingletonMicronautUne seule instanceUse cases, repositories
@ControllerMicronautAPI RESTControllers REST
@Get/@Post/@Put/@DeleteMicronautVerbe HTTPCRUD endpoints
@QueryValueMicronautParamètre URL (?key=value)Filtres, recherche
Path paramMicronautVariable chemin (/users/123)ID de ressource
@BodyMicronautCorps requête JSONCréation/modification

Tips & Best Practices

1. Injection de Dépendances

Micronaut injecte automatiquement les dépendances avec @RequiredArgsConstructor - pas besoin de @Inject ou @Autowired !

@Singleton @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; // Injecté automatiquement }

2. Ordre des Annotations Lombok

L’ordre des annotations Lombok peut affecter le code généré.

@RequiredArgsConstructor @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class MyClass { SomeService service; }

3. Retour JSON Automatique

Micronaut sérialise automatiquement vos objets en JSON avec Jackson.

@Get public TrendResponseDto getTrends() { return new TrendResponseDto("java", "FR", 85); }

Réponse HTTP automatique :

{ "keyword": "java", "region": "FR", "interestScore": 85 }

4. Combo Gagnant

La combinaison la plus utilisée dans le projet :

@Singleton @RequiredArgsConstructor @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class GetTrendsUseCase { TrendRepository repository; public Optional<Trend> execute(String keyword) { return repository.findByKeyword(keyword); } }

Ressources

Prochaines étapes

Maintenant que vous maîtrisez les annotations, explorez les concepts fondamentaux de Micronaut et l’architecture hexagonale.

Last updated on