Formation Java / Spring Boot – Qualité API & outils professionnels
À l’issue de cette journée, vous serez capable de :
JPA/Hibernate
@NotNull
@NotBlank
@Positive
@Size
@ControllerAdvice
Nous avons déjà découvert les bases du Mapping la semaine dernière. Nous allons approfondir certains concepts.
Sans validation :
Une API professionnelle valide les données dès l’entrée, voire même dès le front-end dans certaine configuration.
Spring Boot intègre Hibernate Validator.
Ajouter dépendance si nécessaire :
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
On ne valide pas les entités directement, on valide les DTO d’entrée.
public record CompteCreationDTO( @NotBlank(message = "Le numéro est obligatoire") String numero, @NotNull(message = "Le solde initial est obligatoire") @Positive(message = "Le solde doit être positif") BigDecimal solde ) {}
@PostMapping public ResponseEntity<?> creerCompte( @Valid @RequestBody CompteCreationDTO dto) { service.creerCompte(dto); return ResponseEntity.ok().build(); }
@Valid déclenche automatiquement la validation.
@Valid
Si le JSON est invalide :
{ "solde": -100 }
Spring retourne une erreur 400 avec les détails. Nous allons dans la suite, contrôler la structure de cette erreur.
Lien vers une explication sur l’intérêt ou pas d’utiliser un @ControllerAdvice
Dans une application professionnelle, on contrôle les réponses.
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity<?> handleIllegalArgument( IllegalArgumentException ex) { return ResponseEntity .badRequest() .body(Map.of("error", ex.getMessage())); } }
@ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<?> handleValidationErrors( MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getFieldErrors() .forEach(error -> errors.put(error.getField(), error.getDefaultMessage())); return ResponseEntity.badRequest().body(errors); }
Le JSON retourne les messages d’erreur liés à la saisie.
{ "numero": "Le numéro est obligatoire", "solde": "Le solde doit être positif" }
C’est Lisible et Structuré.
Même si vous n’allez pas l’utiliser, il est intéressant de le découvrir et le tester. Vous le connaissez déjà, du coup, on utilisera Bruno pour changer.
Bruno
Ajouter la dépendance sanchant que la version peut varier :
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.3.0</version> </dependency>
URL :
http://localhost:8080/swagger-ui.html
@Operation(summary = "Créer un compte bancaire") @PostMapping public ResponseEntity<?> creerCompte( @Valid @RequestBody CompteCreationDTO dto) { ... }
Swagger génère automatiquement :
Bruno est un outil moderne pour :
Bruno fonctionne avec des fichiers .bru. Les requêtes peuvent être versionnées dans Git.
.bru
Site officiel : https://www.usebruno.com/
Créer un fichier list-comptes.bru
list-comptes.bru
meta { name: Liste comptes type: http seq: 1 } get { url: http://localhost:8080/api/comptes }
meta { name: Créer compte type: http seq: 2 } post { url: http://localhost:8080/api/comptes body: json } body:json { { "numero": "FR100", "solde": 500 } }
Les deux sont complémentaires.
/bruno
Maintenant, vous devez avoir réalisé :
Vous savez maintenant :
Pour gagner du temps, générez vos entités depuis votre BD (avec Eclipse) car pour IntelliJ, il faut la version entreprise.