Documentation

Plugin REST
Controllers, DTOs et dérivation HTTP automatique.

Référence complète du plugin REST HexaGlue : génération de controllers Spring MVC, DTOs avec validation, et dérivation automatique des verbes HTTP depuis les ports driving.

Découvrir toutes les fonctionnalités Ce que le plugin génère, analyse ou produit.
Fonctionnalités
Installation

Ajouter le plugin REST

pom.xml
<plugin>
<groupId>io.hexaglue</groupId>
<artifactId>hexaglue-maven-plugin</artifactId>
<version>6.1.1</version>
<extensions>true</extensions>
<configuration>
<basePackage>com.acme.shop</basePackage>
</configuration>
<dependencies>
<dependency>
<groupId>io.hexaglue.plugins</groupId>
<artifactId>hexaglue-plugin-rest</artifactId>
<version>3.1.1</version>
</dependency>
</dependencies>
</plugin>

La génération s'exécute automatiquement lors de la phase generate-sources (mvn compile). Les artefacts sont générés dans target/generated-sources/hexaglue/.

Le plugin analyse les ports driving (interfaces de cas d'utilisation) et génère pour chacun un controller REST complet avec DTOs et validation.

  • <extensions>true</extensions> : active le binding automatique aux phases Maven. Les goals HexaGlue se déclenchent sans configuration supplémentaire lors de mvn compile.
  • <basePackage> : package racine à analyser. Le plugin REST découvre automatiquement les ports driving de ce package et de ses sous-packages.
  • Le plugin REST est déclaré comme <dependency> du plugin Maven, pas du projet. HexaGlue le découvre automatiquement via ServiceLoader.

Le plugin REST se combine naturellement avec les plugins JPA et Audit. HexaGlue exécute d'abord les générateurs (REST, JPA), puis l'audit valide l'architecture complète.

Le plugin génère du code qui utilise Spring MVC et Bean Validation. Ajoutez ces dépendances à votre pom.xml :

pom.xml : dépendances requises
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Optionnel : documentation OpenAPI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
Configuration

Paramètres Maven

La configuration de la génération se fait via les paramètres <configuration> du plugin Maven dans le pom.xml.
Ces paramètres contrôlent le package analysé, le répertoire de sortie et le comportement en cas de types non classifiés.
Le paramètre skip peut aussi être passé en ligne de commande via -Dhexaglue.skip=true.
OptionDéfaut
basePackage(requis)
failOnUnclassifiedfalse
outputDirectory/generated-sources/hexaglue
skipfalse
skipValidationfalse
tolerantResolutionfalse
Configuration

Options YAML

Le fichier hexaglue.yaml, placé à la racine du projet (à côté du pom.xml), centralise la configuration de HexaGlue et de tous ses plugins.
Les options ci-dessous se configurent dans la section plugins.io.hexaglue.plugin.rest: du fichier YAML.
Les paramètres Maven (<configuration>) sont prioritaires sur les valeurs YAML.
OptionTypeDéfaut
controllerSuffixstringController
requestDtoSuffixstringRequest
responseDtoSuffixstringResponse
basePathstring/api
exceptionHandlerClassNamestringGlobalExceptionHandler
apiPackagestring(auto-détecté)
targetModulestring(auto-détecté)
generateOpenApiAnnotationsbooleantrue
flattenValueObjectsbooleantrue
generateExceptionHandlerbooleantrue
generateConfigurationbooleantrue
exceptionMappingsmap(vide)
Génération

Ce qui est généré pour chaque port driving

Pour chaque port driving (interface de cas d'utilisation) détecté dans le domaine, le plugin produit jusqu'à 5 types d'artefacts. La génération du handler d'exceptions et de la configuration est contrôlable individuellement.
ArtefactExemple (OrderUseCases)
ControllerOrderController
Request DTOCreateOrderRequest
Response DTOOrderResponse
Exception HandlerGlobalExceptionHandler
ConfigurationRestConfiguration

Les identifiants de type wrapper (comme record OrderId(UUID value)) sont automatiquement dépliés vers leur type primitif dans les DTOs et les @PathVariable. L'identifiant est reconstruit via la factory OrderId.of(uuid) dans le controller.

Les artefacts sont organisés en sous-packages : controller, dto, exception et config. Le package parent est configurable via apiPackage.

Dérivation HTTP

Des signatures de méthode aux endpoints REST

Le plugin analyse chaque méthode du port driving et dérive automatiquement le verbe HTTP, le chemin et le code de statut. Cette dérivation repose sur le nom de la méthode, ses paramètres et son type de retour.
PréfixeVerbeCheminStatut
create, add, registerPOST/201
get, find, loadGET/{id}200
getAll, list, findAllGET/200
search, queryGET/search200
update, modify, editPUT/{id}200
delete, remove, archiveDELETE/{id}204
countGET/count200
exists, is, hasGET/{id}/exists200
(autre commande avec identifiant)POST/{id}/{action}200/204

Le plugin résout automatiquement les collisions d'URL. Si deux méthodes produisent le même verbe et chemin, l'une d'elles est préfixée avec le nom de la méthode en kebab-case. Un avertissement est émis dans les logs Maven.

Les méthodes de type query (retournant une valeur sans effet de bord) sont mappées sur GET. Les méthodes de type command (modifiant l'état) sont mappées sur POST, PUT ou DELETE selon le préfixe. Les commandes retournant void reçoivent le statut 204.

Exemples

Code généré

Voici des extraits représentatifs du code généré par le plugin REST pour un domaine Order.

Controller

OrderController.java
@RestController
@RequestMapping("/api/orders")
@Tag(name = "Orders", description = "Order management operations")
public class OrderController {
private final OrderUseCases orderUseCases;
public OrderController(OrderUseCases orderUseCases) {
this.orderUseCases = orderUseCases;
}
@PostMapping
@Operation(summary = "Create order")
public ResponseEntity<Object> createOrder(
@Valid @RequestBody CreateOrderRequest request) {
var result = orderUseCases.createOrder(request.customerId(), ...);
return ResponseEntity.status(201).body(OrderResponse.from(result));
}
@GetMapping("/{id}")
@Operation(summary = "Get order")
public ResponseEntity<Object> getOrder(@PathVariable UUID id) {
var result = orderUseCases.getOrder(OrderId.of(id));
return ResponseEntity.ok(OrderResponse.from(result));
}
}

Request et Response DTOs

DTOs générés
// Request DTO : validation automatique depuis les types du domaine
public record CreateOrderRequest(
@NotNull UUID customerId,
@NotBlank String productName,
@Positive int quantity
) {}
// Response DTO : factory from() pour la projection domaine → REST
public record OrderResponse(
UUID id,
UUID customerId,
String productName,
String status
) {
public static OrderResponse from(Order source) {
return new OrderResponse(
source.getId().value(),
source.getCustomerId().value(),
source.getProductName(),
source.getStatus().name());
}
}

Exception Handler

GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, Object> handleIllegalArgument(
IllegalArgumentException ex) {
return Map.of(
"error", "BAD_REQUEST",
"message", ex.getMessage(),
"status", 400);
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, Object> handleException(Exception ex) {
return Map.of(
"error", "INTERNAL_SERVER_ERROR",
"message", ex.getMessage(),
"status", 500);
}
}

Configuration

La classe @Configuration expose les application services via leurs ports driving, permettant à Spring d'injecter automatiquement les implémentations dans les controllers.

RestConfiguration.java
@Configuration
public class RestConfiguration {
@Bean
public OrderUseCases orderUseCases(OrderService orderService) {
return orderService;
}
}
Multi-module

Routage des artefacts en multi-module

En multi-module, les artefacts REST doivent être générés dans le module API, pas dans le module de domaine. Le plugin résout le module cible selon cette priorité :
  1. 1
    Configuration explicite : targetModule: "shop-api" dans hexaglue.yaml
  2. 2
    Auto-routage par convention : si un seul module a le rôle API, les artefacts y sont routés automatiquement
  3. 3
    Défaut : si ni configuration ni convention ne s'appliquent, les artefacts sont écrits dans le répertoire de sortie par défaut

Si plusieurs modules ont le rôle API et qu'aucun targetModule n'est configuré, le plugin émet un avertissement et utilise le répertoire de sortie par défaut. Préférez la configuration explicite dans ce cas.

hexaglue.yaml : multi-module
modules:
shop-core:
role: DOMAIN
shop-api:
role: API
shop-persistence:
role: INFRASTRUCTURE
plugins:
io.hexaglue.plugin.rest:
targetModule: "shop-api"
basePath: "/api/v2"
Exemple

Configuration complète

Cet exemple regroupe toutes les options du plugin REST dans un seul fichier hexaglue.yaml. En pratique, seules les options dont vous souhaitez modifier la valeur par défaut sont nécessaires.
hexaglue.yaml : toutes les options
plugins:
io.hexaglue.plugin.rest:
# Package cible (auto-détecté si omis)
apiPackage: "com.acme.shop.api"
# Suffixes de nommage
controllerSuffix: "Controller"
requestDtoSuffix: "Request"
responseDtoSuffix: "Response"
# URL de base
basePath: "/api"
# Annotations OpenAPI (@Tag, @Operation, @ApiResponse)
generateOpenApiAnnotations: true
# Aplatir les value objects multi-champs dans les DTOs
flattenValueObjects: true
# Handler d'exceptions global (@RestControllerAdvice)
generateExceptionHandler: true
exceptionHandlerClassName: "GlobalExceptionHandler"
# Classe @Configuration avec @Bean pour les ports
generateConfiguration: true
# Mappings exception → HTTP status personnalisés
exceptionMappings:
"com.acme.shop.OrderNotFoundException": 404
"com.acme.shop.InsufficientStockException": 409
# Multi-module (optionnel)
# targetModule: "shop-api"

Besoin d'une génération sur mesure ?

Ce plugin couvre les patterns d'API REST les plus courants, mais chaque entreprise a ses propres conventions et exigences techniques. L'architecture ouverte d'HexaGlue vous permet de créer des plugins adaptés à votre stack.

Concentrez-vous sur les cas d'utilisation.
Générez les controllers en quelques lignes.

Définissez vos ports driving, HexaGlue génère les endpoints REST avec validation et documentation OpenAPI.