CodeGym /Cours /Java Server /Sous le capot du backend 🔧

Sous le capot du backend 🔧

Java Server
Niveau 1, Leçon 2
Disponible

1. Après la belle flèche, le travail commence 🚀

Quand quelqu'un entend parler de backend pour la première fois, il s'accroche habituellement à la partie la plus visible du tableau — le traitement de la requête. On a l'impression que tout l'essentiel vit dans une seule méthode : reçu des données, fait le travail, renvoyé la réponse. Mais dès qu'on essaie de transformer cette méthode en projet, une réalité infrastructurelle se construit immédiatement autour.

Il faut comprendre comment le projet démarre. Où se trouve son code, comment il s'assemble, quelles sont ses dépendances, comment il se lance sans le bouton vert de l'IDE. Il faut décider sous quelle forme le système parle avec le monde extérieur. Maintenir la frontière entre les objets internes de l'application et ce qui arrive ou part sur le réseau. Faire en sorte que les paramètres puissent être changés sans réécrire les sources. Avoir au moins un moyen correct d'analyser les problèmes quand une requête n'est pas passée comme prévu.

C'est pourquoi le backend se lit mal comme « une classe avec de la logique ». Un vrai comportement backend a une scène sur laquelle il se joue. Et cette scène n'est pas composée seulement de méthodes de code, mais aussi d'un build, de contrats, d'une configuration, de logs et de frontières du système.

Plus tôt tu verras ça, plus facilement tu liras les sujets suivants du cours. Et si tu ne le vois pas, Gradle semble une formalité bizarre, HTTP — « juste le réseau », JSON — « juste une chaîne », et la journalisation — « des messages inutiles ». En réalité, tout ça fait partie d'un même tableau.

2. D'abord le projet doit pouvoir démarrer

Une question très terre-à-terre : comment lancer l'application non seulement chez l'auteur dans l'IDE, mais aussi chez quelqu'un d'autre ? Ce n'est pas un détail d'organisation, c'est la fondation d'un projet backend.

Tant que tu vis dans le monde des petits exercices console, cette douleur peut passer longtemps inaperçue. Tu appuies sur Run — et c'est parti. Mais un projet backend dépend presque immédiatement de la structure des répertoires, des dépendances, des ressources, de la configuration et de la version de l'outil de build. Si tout ça vit seulement dans les paramètres de l'IDE, le projet devient fragile. Il « fonctionne » en apparence, mais seulement dans un univers local très précis 😬.

C'est pourquoi le cours commence son premier module technique non pas par HTTP, mais par Gradle Wrapper. Ça semble anodin, mais c'est une décision très backend. L'application doit s'assembler et se lancer de la même façon pour tout le monde, et non seulement pour une personne avec une machine bien configurée. À partir de ce moment, le projet n'est plus un dossier avec du code, mais un artefact reproductible.

On n'a pas encore besoin d'analyser les détails de build.gradle.kts, mais il est utile de comprendre le principe lui-même : les règles de lancement et d'assemblage sont à côté du code, pas dans ta mémoire. C'est exactement cette maturité que Spring ne remplace pas ensuite, mais présuppose. Même dans le monde Spring Boot, tu vis toujours dans un projet avec un outil de build, des dépendances et un démarrage reproductible.

3. Le format de communication : request, response, HTTP et JSON 📡

Dès que le projet a appris à démarrer, la question suivante surgit immédiatement : sous quelle forme communique-t-il avec le monde extérieur ? C'est là qu'apparaît en backend le mot « contrat » 🧾.

Le contrat n'est ni de la bureaucratie ni une belle documentation pour la documentation. C'est un accord honnête entre deux parties : ce qui compte comme entrée, ce qui compte comme sortie, sous quelle forme arrivent les données, quelles réponses sont possibles, où est l'erreur, où est le succès, ce que signifie l'absence de données, et ce que signifie une mauvaise saisie. Sans un tel accord, n'importe quelle interaction devient vite un « je croyais que tu voulais dire autre chose » 😅.

Plus tard on parlera des méthodes HTTP, des statuts, des headers, des path et query params. Mais dès maintenant, il suffit de voir l'essentiel : le backend ne peut pas vivre seulement d'objets Java internes. Il a une frontière. Et sur cette frontière, les données circulent généralement en JSON, et le sens de l'accord se vérifie avec des outils comme Postman.

Voici un tout petit fragment de transport du futur ReadLater :

{
  // Titre du livre — tel qu'il est transmis par le contrat externe (couche transport)
  "title": "Clean Code",

  // Auteur — fait aussi partie du format externe ; à l'intérieur de l'application, le nom peut être différent
  "author": "Robert C. Martin",

  // Statut — champ autour duquel naissent immédiatement des questions de validation et de valeurs acceptables
  "status": "PLANNED"
}

Le regard naïf dit : « bah, c'est du JSON ». Le regard expérimenté pose d'autres questions 👀. Qui garantit que le champ status est bien arrivé ? Que signifie null ? Peut-on envoyer une chaîne vide ? Est-ce une response ou une request ? Est-ce le modèle interne de l'application ou seulement le format externe ? C'est précisément de telles questions que naissent ensuite les DTO, la validation, le contrat d'erreurs et une vraie pensée API.

C'est là que le rôle de Postman devient clair. Il n'est pas là comme un bouton Send, mais comme un microscope pour le contrat 🔬. Il aide à voir ce qui circule vraiment sur le réseau, quels statuts reviennent, à quoi ressemblent happy-path et negative-path. Ce n'est pas un « outil supplémentaire dans le cours », c'est une façon de travailler avec la frontière d'un système backend comme ingénieur, et non comme spectateur.

4. Les données de transport ne doivent pas se répandre dans l'application

La couche de douleur suivante apparaît juste après le contrat. Même si le JSON est arrivé honnêtement, il faut encore le transformer en objets avec lesquels l'application peut vivre normalement. Et c'est là que le débutant fait souvent une simplification dangereuse : il commence à traîner le format de données externe dans tout le code tel quel.

Le problème est que le modèle de transport et le modèle interne de l'application coïncident rarement à l'identique. Une API externe peut nommer un champ d'une certaine façon, ton domaine — d'une autre. La réponse externe peut contenir plein de choses inutiles. À l'intérieur de l'application, tu peux avoir besoin d'un objet plus propre et plus stable. C'est exactement pour ça que les DTO et le mapping apparaissent en backend.

On n'a pas encore besoin d'une analyse complète de Jackson 3, mais il est utile de voir la forme de la séparation :

// DTO — la forme de transport des données, qui correspond au contrat externe
record CatalogBookDto(
    String title,      // champ venu du JSON externe (tel que nommé à la frontière)
    String author,     // champ venu du JSON externe (peut être nullable/vide — selon le contrat)
    String externalId  // identifiant externe (par exemple, d'un catalogue/service partenaire)
) {}

// Domaine/modèle interne — ce avec quoi il est pratique de vivre à l'intérieur de l'application
record ReadingListItem(
    String title,   // à l'intérieur de l'application, on a peut-être besoin seulement de ça...
    String author   // ...et de ça, sans externalId ni autres détails de transport
) {}

CatalogBookDto — c'est la forme de transport dans laquelle les données sont arrivées de l'extérieur. ReadingListItem — c'est déjà un objet avec lequel il est pratique de vivre à l'intérieur de ReadLater. La différence entre eux peut être petite, ou peut être grande. L'idée est la même : le contrat externe ne doit pas se répandre incontrôlablement dans l'application.

C'est pourquoi dans le programme du cours, après HTTP et JSON, apparaissent logiquement HttpClient, Jackson 3 et la pensée DTO. Ce ne sont pas trois nouveaux jouets à la suite. C'est une même suite pour une tâche très pratique : récupérer du JSON externe, ne pas transformer le projet en soupe de chaînes et maintenir une frontière claire entre la couche transport et le sens interne.

5. La configuration et les logs — ce n'est pas de la décoration, c'est de l'exploitation

Imagine maintenant que notre ReadLater sait déjà consulter le catalogue de livres externe et retourner un résultat. Il s'avère soudain que l'application a des valeurs qu'on ne peut pas toujours garder en hardcode : le baseUrl du service externe, le mode real ou mock, le port du serveur local, éventuellement des timeouts ⏱️. Ce n'est plus de la logique métier. Ce sont les conditions dans lesquelles l'application fonctionne.

C'est là qu'apparaît l'idée d'externalized configuration. Même avant Spring, c'est un sujet à part, parce qu'une application mature ne doit pas nécessiter de modifier les sources chaque fois que l'adresse d'un service ou le mode de lancement change 🔧. Plus tard Spring Boot rendra cette couche beaucoup plus confortable, mais le principe lui-même ne naît pas de Spring. Il est nécessaire dès maintenant.

À côté de la configuration, la journalisation arrive presque immédiatement 📝. Dès que tu as des appels externes, différents modes de fonctionnement et plusieurs étapes à l'intérieur du traitement d'une requête, println cesse d'être anodin. On a besoin de niveaux de logs, de messages clairs, d'une distinction entre debug, info, warn et error, d'une gestion soigneuse des exceptions. Là encore : plus tard la pile SLF4J + Logback transforme ça en bonne pratique. Mais la douleur est visible avant même l'outil.

C'est pourquoi le module sur la configuration et la journalisation dans ce cours n'est pas ajouté pour la beauté. C'est une leçon précoce sur la culture d'exploitation d'une application backend. Si une application ne peut pas être correctement configurée et si on ne peut pas lire correctement son comportement, elle reste une démonstration, et non un système.

6. La douleur que Spring va soulager

On peut maintenant formuler l'insight principal très directement. Spring n'est pas nécessaire parce que « c'est comme ça dans l'industrie » ni parce que sans lui le backend est interdit. Il est nécessaire parce qu'en backend, il y a trop de travail manuel répétitif 🔧.

Mais ici l'honnêteté d'ingénierie est importante. Spring n'écrit pas la logique métier à ta place. Spring n'invente pas un bon contrat API. Spring ne fait pas qu'un modèle de transport devienne automatiquement un bon modèle de domaine. Il fait autre chose : il supprime une grande couche de routine infrastructurelle, simplifie le câblage des dépendances, la configuration, le code répétitif de la couche web, le travail avec les composants et le cycle de vie de l'application.

C'est pratique à voir dans une carte compacte :

Travail manuel dans un projet backend Pourquoi c'est nécessaire Où tu le verras dans ce cours Ce qui devient plus simple avec Spring ensuite
Assemblage et démarrage reproductibles Pour que le projet ne vive pas seulement dans l'IDE Gradle Wrapper et configuration de base du build Boot et l'écosystème se lisent sans magie, mais la compréhension du build reste ta tâche
Contrat HTTP Pour que le client et le serveur comprennent de la même façon l'entrée et la sortie HTTP, statuts, headers, Postman Spring MVC supprime beaucoup de travail répétitif autour de la frontière web
JSON et formes de transport Pour que les données à la frontière soient explicites JSON, DTO, Jackson 3 Le binding et le mapping deviennent plus confortables, mais le contrat, c'est toi qui le conçois
Client HTTP externe Pour que l'application sache aller dans d'autres systèmes HttpClient, real/mock, erreurs réseau Dans le monde Spring, des couches d'intégration plus confortables apparaissent
Configuration hors du code Pour que le même code fonctionne dans différents modes application.properties, env vars, args Spring Boot rend l'externalized configuration beaucoup plus confortable
Journalisation et diagnostic Pour analyser les comportements et les pannes SLF4J + Logback Une bonne approche de base de la journalisation apparaît plus vite et plus proprement
API HTTP locale Pour voir la couche web de ses propres mains JDK HttpServer, routing, response writing Spring MVC supprime un énorme volume de travail manuel sur la couche web

Spring n'apporte pas une nouvelle physique en backend. Il prend en charge la partie mécanique répétitive. C'est pourquoi ce cours ne concurrence pas Spring, il lui donne une base compréhensible.

7. Comment le programme du cours naît de tout ça

Après cette carte, la structure du cours cesse de paraître aléatoire. D'abord tu rends le projet reproductible via Gradle Wrapper, parce que sans ça tu n'as pas de point d'entrée fiable. Ensuite tu entres dans HTTP, JSON et Postman, parce que c'est le langage de la frontière du système 📡. Puis tu apprends à être un client HTTP vers une API externe et à mapper JSON en DTO, parce que le backend dépend très souvent d'autres services. Après ça, tu mets le projet en ordre via la configuration, la journalisation et la structure. Et seulement ensuite tu montes ta propre API HTTP locale.

C'est précisément pourquoi notre cours semble cohérent. Il va non pas d'une liste d'outils, mais de vraies questions d'ingénierie. Qu'est-ce qui est nécessaire pour qu'un projet backend vive vraiment ? Comment communique-t-il avec le monde extérieur ? Comment va-t-il dans d'autres systèmes ? Comment éviter que le contrat externe se répande dans le code ? Comment monter soi-même une API HTTP ?

Si à ce moment tu te sens nettement plus serein, c'est que ça fonctionne comme prévu 🙀. Tu n'es pas obligé de croire au programme du cours. Sa logique découle de la nature même du travail backend. La prochaine étape depuis ici surgit aussi naturellement : d'accord, puisque le cours est construit autour d'un même parcours et d'un même travail manuel dans un projet backend, quel est exactement le projet qui relie tout ça ? Et c'est là qu'entre en scène ReadLater Starter 🚀.

8. Erreurs typiques 🙉

Erreur n°1 : percevoir build tool, HTTP, JSON, DTO, configuration et logs comme des sujets sans lien entre eux.
Sur le papier ça ressemble à un ensemble de technologies. Dans un vrai système, ce sont des parties d'un même parcours : le projet doit démarrer, avoir une frontière, transporter des données, être configurable et expliquer son comportement. Si tu gardes ce lien dans la tête, le cours se lit bien plus naturellement.

Erreur n°2 : penser que Spring « résout le backend à lui seul ».
Spring aide beaucoup, mais il ne remplace pas la pensée d'ingénierie. Le contrat, le modèle de données, la structure du code, les frontières de responsabilité et la qualité des messages diagnostiques restent ton travail. Le framework facilite le chemin, mais ne le fait pas à ta place.

Erreur n°3 : tirer le JSON externe directement dans toutes les couches de l'application.
Ça semble rapide tant que le projet est petit. Ensuite, tout changement du contrat externe commence à casser la moitié du code. Les DTO et le mapping sont nécessaires non pas pour la cérémonie, mais pour isoler la frontière externe.

Erreur n°4 : considérer la configuration et les logs comme secondaires.
Tant que l'application fait une démonstration sur ta machine, on peut le penser. Mais dès qu'apparaissent des modes de lancement, un service externe et un traitement répété, la configuration et l'observabilité deviennent une partie de la maturité de base du projet.

1
Mission
Java Server, niveau 1, leçon 2
Bloqué
Journal de démarrage et journal de résultat
Journal de démarrage et journal de résultat
1
Mission
Java Server, niveau 1, leçon 2
Bloqué
Route de requête via catalogue et stockage
Route de requête via catalogue et stockage
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION