Créer un projet Spring Boot et un premier endpoint

Première leçon du cours Spring Boot : API REST, en accès libre : environ 18 minutes, 3 exercices et 3 questions de quiz. C'est la leçon de base du catalogue ; dans l'espace étudiant, elle est réécrite pour ton profil.

Objectifs

  • Générer un projet Spring Boot avec Spring Initializr et comprendre sa structure
  • Écrire un contrôleur REST qui renvoie du JSON
  • Démarrer l'application et appeler l'endpoint avec curl

Spring Boot@RestControllerSérialisation JSON avec Jackson

Spring Boot est le framework le plus utilisé pour créer des API web en Java. Il s’appuie sur Spring Framework et apporte deux choses essentielles : une configuration automatique (il devine la configuration à partir des dépendances présentes) et un serveur web embarqué (Tomcat par défaut). Résultat : une API se lance avec un simple main, sans installer de serveur.

Ce cours utilise Spring Boot 4.1 (Spring Framework 7) avec Java 25, la version LTS actuelle de Java.

Générer le projet

Le site officiel Spring Initializr (start.spring.io), aussi intégré à IntelliJ IDEA et VS Code, génère le squelette. Il propose par défaut Gradle et Java 17 : choisissez Maven, Java 25, un groupe (fr.boutique) et la dépendance Spring Web. En ligne de commande :

curl https://start.spring.io/starter.zip -d type=maven-project -d dependencies=web -d javaVersion=25 \
     -d groupId=fr.boutique -d artifactId=boutique -d packageName=fr.boutique -d baseDir=boutique -o boutique.zip
unzip boutique.zip

Structure obtenue :

boutique/
├── pom.xml                       # dépendances (spring-boot-starter-webmvc...)
├── mvnw                          # Maven Wrapper : pas besoin d'installer Maven
└── src/
    ├── main/java/fr/boutique/BoutiqueApplication.java
    ├── main/resources/application.properties
    └── test/java/fr/boutique/BoutiqueApplicationTests.java

Les starters (spring-boot-starter-webmvc, -validation, -data-jpa…) regroupent des dépendances cohérentes dont Spring Boot gère les versions. La dépendance « Spring Web » correspond au starter spring-boot-starter-webmvc (nouveau nom depuis Spring Boot 4) ; Spring Initializr ajoute aussi son starter de test, spring-boot-starter-webmvc-test, car chaque module a désormais le sien.

La classe principale

package fr.boutique;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // auto-configuration + scan des composants de fr.boutique.*
public class BoutiqueApplication {
    public static void main(String[] args) {
        SpringApplication.run(BoutiqueApplication.class, args);
    }
}

Spring scanne le package de cette classe et ses sous-packages : placez vos contrôleurs dans fr.boutique.produit, par exemple, jamais dans un package « à côté ».

Un premier contrôleur REST

package fr.boutique.produit;

import org.springframework.web.bind.annotation.*;
import java.util.List;

record ProduitDto(long id, String nom, double prix) {}

@RestController                 // les valeurs renvoyées deviennent le corps de la réponse
@RequestMapping("/api")         // préfixe commun aux routes de la classe
class BonjourController {

    @GetMapping("/bonjour")     // GET /api/bonjour
    String bonjour() {
        return "Bonjour depuis Spring Boot";
    }

    @GetMapping("/produits")    // GET /api/produits
    List<ProduitDto> produits() {
        return List.of(new ProduitDto(1, "Clavier", 45.5),
                       new ProduitDto(2, "Écran", 180));
    }
}

@RestController combine @Controller et @ResponseBody. La bibliothèque Jackson, incluse dans le starter webmvc (Jackson 3 depuis Spring Boot 4, packages tools.jackson.*), convertit automatiquement le record en JSON : [{"id":1,"nom":"Clavier","prix":45.5}, ...]. Les records sont parfaits pour cela : immuables, concis, sérialisés sans configuration.

Lancer et tester

./mvnw spring-boot:run                 # démarre sur le port 8080
curl http://localhost:8080/api/produits

Pour changer le port, ajoutez dans application.properties :

server.port=8081
spring.application.name=boutique

Les journaux de démarrage indiquent Tomcat started on port 8081. Si le port est déjà occupé, l’application refuse de démarrer : arrêtez l’ancienne instance ou changez de port.

À retenir

  • Spring Boot = Spring + auto-configuration + serveur embarqué.
  • Une méthode d’un @RestController annotée @GetMapping devient un endpoint.
  • Les objets renvoyés sont sérialisés en JSON par Jackson.

Exercices

Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.

  1. TâcheDifficulté 12 indices

    Générer et lancer votre première API

    Dans votre environnement de travail, générez un projet Spring Boot 4 (Maven, Java 25, dépendance Spring Web), par exemple avec curl https://start.spring.io/starter.zip -d type=maven-project -d dependencies=web -d javaVersion=25 -d groupId=fr.boutique -d artifactId=boutique -d packageName=fr.boutique -d baseDir=boutique -o boutique.zip puis unzip boutique.zip && cd boutique (sans type=maven-project, Spring Initializr génère un projet Gradle, sans pom.xml ni mvnw). Créez un @RestController exposant GET /api/bonjour qui renvoie un record Message(String texte) et GET /api/produits qui renvoie une liste de trois produits. Lancez l’application avec ./mvnw spring-boot:run et appelez les deux endpoints avec curl.

    • L'application démarre et les journaux affichent « Tomcat started on port 8080 »
    • curl http://localhost:8080/api/bonjour renvoie un objet JSON {"texte": ...}
    • curl http://localhost:8080/api/produits renvoie un tableau JSON de trois produits
    • Le contrôleur est dans un sous-package de la classe @SpringBootApplication
  2. CodeDifficulté 2Sandbox serveur2 indices

    Sérialiser un record en JSON comme Jackson

    Pour comprendre ce que fait Jackson, écrivez static String toJson(Produit p) pour le record Produit(long id, String nom, double prix, boolean disponible). Le format est compact, dans l’ordre des composants :

    {"id":1,"nom":"Clavier","prix":45.5,"disponible":true}

    Les chaînes sont entre guillemets et les caractères \ et " qu’elles contiennent sont échappés (précédés d’un \). Chaque ligne de l’entrée est id;nom;prix;disponible ; affichez le JSON de chaque produit.

    import java.util.*;
    
    public class Main {
        static String echapper(String s) {
            // TODO : échapper \ puis "
            return s;
        }
    
        static String toJson(Produit p) {
            // TODO
            return "";
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            while (sc.hasNextLine()) {
                String l = sc.nextLine();
                if (l.isBlank()) continue;
                String[] c = l.split(";");
                Produit p = new Produit(Long.parseLong(c[0]), c[1], Double.parseDouble(c[2]), Boolean.parseBoolean(c[3]));
                System.out.println(toJson(p));
            }
        }
    }
    
    record Produit(long id, String nom, double prix, boolean disponible) {}
  3. QCMDifficulté 11 indice

    @RestController

    Quelle est la différence entre @RestController et @Controller ?

    • @RestController ajoute @ResponseBody : la valeur renvoyée est écrite dans le corps de la réponse (JSON)
    • @RestController n'accepte que les requêtes GET
    • Il n'y a aucune différence

Quiz de fin de leçon

  1. Quel serveur web Spring Boot embarque-t-il par défaut avec le starter Spring Web ?

    • Apache HTTPD
    • Tomcat
    • Nginx
  2. Quel fichier contient la configuration de l’application (port, nom…) ?

    • pom.xml
    • src/main/resources/application.properties
    • BoutiqueApplication.java
  3. Quelle bibliothèque convertit les objets Java en JSON dans une application Spring Boot web ?

    • Jackson
    • Hibernate
    • JUnit

La suite du cours

  1. Routes, verbes HTTP et ResponseEntity20 min
  2. DTO et validation des données20 min
  3. Couche service et injection de dépendances20 min
  4. Gestion globale des erreurs et tests de l'API22 min

Spring Boot : API REST · Avancé · 2 h 40