Avant de plonger dans le vif du sujet, rappelons rapidement ce qu'est MapStruct. C'est un générateur de code qui crée des mappers de beans type-safe à la compilation. Pas de surcharge à l'exécution, pas de magie de réflexion - juste du code Java pur et efficace. Voici un aperçu de ce à quoi ressemble un mapper basique :
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDTO mapToDTO(User user);
}
Simple, non ? Mais attention, ce n'est que le début !
Les 10 astuces MapStruct que vous ne saviez pas dont vous aviez besoin
1. Mapping avec Contexte : L'Ingrédient Secret
Avez-vous déjà eu besoin de passer des informations supplémentaires à votre mapper ? Voici l'annotation @Context :
@Mapper
public interface UserMapper {
@Mapping(target = "role", source = "user")
UserDTO mapToDTO(User user, @Context SecurityContext securityContext);
default String mapRole(User user, @Context SecurityContext securityContext) {
return securityContext.isAdmin() ? "ADMIN" : user.getRole();
}
}
Vous pouvez maintenant injecter un contexte d'exécution dans votre logique de mapping. Sympa, non ?
2. Mappings de Méthodes Personnalisées : Quand le Standard ne Suffit Pas
Parfois, vous devez mettre la main à la pâte et écrire une logique de mapping personnalisée :
@Mapper
public interface DateMapper {
@Mapping(target = "formattedDate", source = "date", qualifiedByName = "formatDate")
DateDTO map(DateEntity date);
@Named("formatDate")
default String formatDate(LocalDate date) {
return date != null ? date.format(DateTimeFormatter.ISO_LOCAL_DATE) : null;
}
}
Astuce : Utilisez @Named pour garder vos méthodes personnalisées organisées et réutilisables à travers différents mappers.
3. Mapping de Collections : Parce qu'Une Seule ne Suffit Jamais
MapStruct gère les collections comme un pro :
@Mapper
public interface ProductMapper {
List mapToDTOList(List products);
Set mapToProductNames(List products);
}
Il applique automatiquement le mapping d'éléments à chaque élément de la collection. Magique !
4. Mapping d'Objets Imbriqués : Plongée en Profondeur
Vous traitez des graphes d'objets complexes ? MapStruct est là pour vous :
@Mapper
public interface OrderMapper {
@Mapping(target = "customerName", source = "customer.name")
@Mapping(target = "orderItems", source = "items")
OrderDTO mapToDTO(Order order);
@Mapping(target = "productName", source = "product.name")
OrderItemDTO mapToItemDTO(OrderItem item);
}
Il gère sans effort les objets imbriqués, vous évitant le cauchemar du mapping manuel.
5. Mapping Conditionnel : L'Art de la Prise de Décision
Parfois, vous devez prendre des décisions de mapping à la volée :
@Mapper
public interface UserMapper {
@Mapping(target = "status", expression = "java(mapStatus(user))")
UserDTO mapToDTO(User user);
default String mapStatus(User user) {
return user.getLastLoginDate() != null &&
user.getLastLoginDate().isAfter(LocalDate.now().minusDays(30))
? "ACTIVE" : "INACTIVE";
}
}
Utilisez des expressions pour injecter une logique complexe dans vos mappings.
6. Ignorer des Champs : L'Art du Mapping Sélectif
Parfois, moins c'est plus. Ignorez les champs dont vous n'avez pas besoin :
@Mapper
public interface UserMapper {
@Mapping(target = "password", ignore = true)
@Mapping(target = "createdAt", ignore = true)
UserDTO mapToDTO(User user);
}
Parfait lorsque vous traitez des données sensibles ou des champs qui n'appartiennent pas à votre DTO.
7. Mapping Inverse : Aller dans les Deux Sens
Besoin de mapper dans les deux sens ? MapStruct vous couvre :
@Mapper
public interface UserMapper {
@Mapping(target = "id", ignore = true)
User mapToEntity(UserDTO dto);
UserDTO mapToDTO(User user);
}
Définissez simplement les deux méthodes, et MapStruct gérera le mapping bidirectionnel pour vous.
8. Valeurs par Défaut : Remplir les Blancs
Parfois, vous devez fournir des valeurs par défaut pour les données manquantes :
@Mapper
public interface ProductMapper {
@Mapping(target = "inStock", constant = "true")
@Mapping(target = "category", defaultValue = "UNCATEGORIZED")
ProductDTO mapToDTO(Product product);
}
Utilisez constant pour les valeurs codées en dur et defaultValue pour les valeurs de secours lorsque la source est nulle.
9. Avant et Après le Mapping : La Touche Finale
Besoin d'effectuer des opérations avant ou après le mapping ? Voici @BeforeMapping et @AfterMapping :
@Mapper
public abstract class OrderMapper {
@Mapping(target = "total", ignore = true)
public abstract OrderDTO mapToDTO(Order order);
@AfterMapping
protected void calculateTotal(Order order, @MappingTarget OrderDTO orderDTO) {
orderDTO.setTotal(order.getItems().stream()
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum());
}
}
Parfait pour des calculs complexes ou des ajustements de dernière minute.
10. Annotations Personnalisées MapStruct : La Puissance de l'Abstraction
Créez vos propres annotations pour encapsuler des modèles de mapping communs :
@Retention(RetentionPolicy.CLASS)
@Mapping(target = "id", ignore = true)
@Mapping(target = "createdAt", expression = "java(java.time.LocalDateTime.now())")
public @interface ToEntity { }
@Mapper
public interface UserMapper {
@ToEntity
User mapToEntity(UserDTO dto);
}
Cette approche aide à garder vos mappers propres et favorise la réutilisabilité dans votre code.
Conclusion : La Magie de MapStruct Dévoilée
Voilà - 10 astuces MapStruct qui propulseront votre jeu de mapping Quarkus au niveau supérieur. Des mappings sensibles au contexte aux annotations personnalisées, MapStruct regorge de fonctionnalités qui peuvent simplifier même les transformations d'objets les plus complexes.
Rappelez-vous, la clé pour maîtriser MapStruct est l'expérimentation. N'ayez pas peur de plonger dans la documentation et d'essayer différentes combinaisons de ces techniques. Votre futur vous (et vos relecteurs de code) vous remercieront pour le code de mapping propre, efficace et maintenable que vous produirez.
Alors, la prochaine fois que vous vous surprenez à vouloir utiliser ce mélangeur manuel de setters, prenez du recul et demandez-vous : "Que ferait MapStruct ?" Il y a de fortes chances qu'il ait une astuce dans sa manche qui facilitera grandement votre vie.
Bon mapping, ninjas de Quarkus ! 🚀
"L'art du mapping n'est pas de créer de nouveaux objets, mais de révéler les relations entre ceux qui existent déjà." - Développeur Anonyme (probablement)
P.S. N'oubliez pas de mettre une étoile au dépôt MapStruct sur GitHub si vous le trouvez utile. Les projets open source prospèrent grâce au soutien de la communauté !