Chapitre 3.5 — Démarrer BookLab
Partie 3 : Installation & environnement — Chapitre 5/5 Version de référence : Symfony 7.4 / PostgreSQL 16.
⏱️ TL;DR
- On crée le projet fil rouge :
symfony new booklab --version="7.4.*" --webapp, puisgit init.- On ajoute Doctrine (
composer require orm) et MakerBundle (composer require --dev maker).- On connecte une base : PostgreSQL (via Docker) ou SQLite (un fichier, zéro install), puis
doctrine:database:create.- On génère un premier contrôleur (
make:controller HomeController) et une route de santé/api/healthqui renvoie du JSON — le premier signe de vie de l’API.symfony serve→ l’écran s’affiche. Premier commit. BookLab existe.- À partir d’ici, chaque partie ajoute une couche à ce projet.
🎯 Objectifs
- Initialiser BookLab (projet + git + Doctrine + Maker).
- Configurer et créer la base de données (PostgreSQL ou SQLite).
- Créer un premier contrôleur et une route JSON de santé.
- Servir l’application et réaliser le premier commit.
1. Créer le projet et le dépôt
symfony new booklab --version="7.4.*" --webapp
cd booklab
git init
git add -A && git commit -m "Squelette Symfony 7.4 (webapp) pour BookLab"ℹ️
symfony newinitialise déjà un dépôt git dans la plupart des cas ; si c’est le cas,git initest inutile. Vérifiez avecgit status.
2. Ajouter Doctrine et le MakerBundle
composer require orm # Doctrine ORM + DoctrineBundle (via Flex)
composer require --dev maker # générateurs make:*Flex crée config/packages/doctrine.yaml et ajoute DATABASE_URL dans .env. On va maintenant pointer cette URL vers une vraie base.
3. Connecter une base de données
Deux options. Choisissez selon votre confort.
Option A — PostgreSQL via Docker (recommandé, proche prod)
Le compose.yaml fourni déclare déjà PostgreSQL. On le démarre :
docker compose up -dAvec la Symfony CLI, DATABASE_URL est injectée automatiquement (chapitre 3.2). Si vous n’utilisez pas la CLI, renseignez-la dans .env.local :
# .env.local (non committé)
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"Option B — SQLite (zéro installation, pour démarrer)
Un simple fichier, aucune install de serveur :
# .env.local
DATABASE_URL="sqlite:///%kernel.project_dir%/var/booklab.db"💡 Pour un dev Next.js : SQLite ici, c’est l’équivalent d’un « je démarre avec une base fichier pour ne pas m’embêter ». Parfait pour apprendre ; on passera à PostgreSQL pour tout ce qui touche aux fonctionnalités avancées (types JSON, contraintes, plein texte). BookLab cible PostgreSQL en vrai.
Créer la base
php bin/console doctrine:database:create
# Created database "app" for connection named default(En SQLite, cela crée le fichier var/booklab.db.)
4. Un premier contrôleur : la route de santé
Générons un contrôleur avec le Maker :
php bin/console make:controller HomeControllerPuis remplaçons son contenu par une page d’accueil et une route de santé JSON (le premier endpoint que consommera, plus tard, le front Next.js) :
// src/Controller/HomeController.php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HomeController extends AbstractController
{
#[Route('/', name: 'home', methods: ['GET'])]
public function index(): Response
{
return $this->render('home/index.html.twig', [
'app_name' => 'BookLab',
]);
}
#[Route('/api/health', name: 'api_health', methods: ['GET'])]
public function health(): JsonResponse
{
return $this->json([
'status' => 'ok',
'app' => 'BookLab',
'time' => (new \DateTimeImmutable())->format(\DateTimeInterface::ATOM),
]);
}
}Deux routes, déclarées par attribut #[Route] (chapitre 1.5) : / rend une page HTML via Twig, /api/health renvoie du JSON via $this->json(...) (un raccourci qui sérialise un tableau en JsonResponse).
Créons le template minimal :
{# templates/home/index.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}{{ app_name }}{% endblock %}
{% block body %}
<h1>{{ app_name }}</h1>
<p>Le back-office arrive. L'API répond déjà sur <code>/api/health</code>.</p>
{% endblock %}⚠️ Piège MDX/Twig : dans ce cours, les accolades Twig (
{{ … }},{% … %}) sont dans des blocs de code — c’est indispensable, car hors bloc de code, MDX interpréterait{comme du JavaScript. Dans votre projet, ce sont bien sûr des templates Twig normaux.
5. Servir et vérifier
symfony serve -d- Ouvrez
https://localhost:8000/→ la page « BookLab » s’affiche. - Ouvrez
https://localhost:8000/api/health→ vous obtenez :
{ "status": "ok", "app": "BookLab", "time": "2026-07-09T12:00:00+00:00" }Vérifiez aussi que le routing est correct en ligne de commande :
php bin/console debug:router
# affiche la table des routes : home GET /, api_health GET /api/health, ...debug:router liste toutes les routes détectées (avec leur nom, méthode, chemin) — un outil que vous consulterez souvent.
6. Premier commit de BookLab
git add -A
git commit -m "BookLab : Doctrine + base + route d'accueil et /api/health"BookLab existe : un projet Symfony 7.4 qui tourne, connecté à une base, avec une première route HTML et une première route JSON. La suite du cours va l’étoffer, partie après partie :
💡 Pour un dev Next.js : à ce stade, mentalement, vous avez fait tourner « l’API backend ». Dans quelques parties, un
fetch('https://localhost:8000/api/health')depuis un composant Next.js recevra ce JSON — c’est déjà l’architecture cible en germe.
✏️ Exercices
Exercice 1. Ajoutez une route GET /api/version qui renvoie { "version": "1.0.0" } en JSON. Écrivez la méthode.
✅ Solution
#[Route('/api/version', name: 'api_version', methods: ['GET'])]
public function version(): JsonResponse
{
return $this->json(['version' => '1.0.0']);
}(À placer dans HomeController. Vérifier avec php bin/console debug:router puis un appel à /api/version.)
Exercice 2. Vous n’avez ni Docker ni PostgreSQL et voulez juste avancer. Quelle configuration de base choisissez-vous, et quelle commande crée la base ?
✅ Solution
SQLite : dans .env.local, DATABASE_URL="sqlite:///%kernel.project_dir%/var/booklab.db". Puis php bin/console doctrine:database:create crée le fichier var/booklab.db. Aucun serveur à installer. (On migrera vers PostgreSQL plus tard pour les fonctionnalités avancées.)
Exercice 3. Après avoir ajouté une route, comment vérifiez-vous sans navigateur qu’elle est bien enregistrée ?
✅ Solution
php bin/console debug:router liste toutes les routes (nom, méthode HTTP, chemin). On peut cibler une route précise : php bin/console debug:router api_health. Utile pour confirmer qu’un attribut #[Route] a bien été pris en compte.
🧠 Quiz de révision
1. Quelle commande crée la base de données une fois DATABASE_URL configurée ?
DATABASE_URL configurée ?php bin/console doctrine:database:create.
2. Comment renvoie-t-on du JSON depuis un contrôleur ?
Avec $this->json($data) (hérité d’AbstractController), qui sérialise $data en JsonResponse.
3. Quelle commande liste toutes les routes de l’application ?
php bin/console debug:router.
4. Quelle base choisir pour démarrer sans rien installer, et quelle est sa limite ?
SQLite (un fichier). Limite : moins de fonctionnalités avancées que PostgreSQL (types JSON riches, plein texte, certaines contraintes) — on migre ensuite.
5. Où sont déclarées les routes / et /api/health de BookLab ?
/ et /api/health de BookLab ?Dans src/Controller/HomeController.php, via des attributs #[Route(...)] au-dessus des méthodes index() et health().
Fin de la Partie 3. BookLab tourne : projet Symfony 7.4, base connectée, une route HTML et une route JSON, le tout versionné. L’environnement est prêt ; on peut maintenant plonger dans le cœur du framework.
Prochaine étape : Partie 4 — HTTP, Kernel, Routing, Controllers — comment Symfony transforme une requête en réponse, en détail.