EasyAdminBundle a été publié à une époque où le réflexe pour avoir un back-office Symfony était soit de coder un CRUD à la main, soit de monter une stack Sonata complète. Le bundle, actuellement en version 5.x, reste l’option par défaut pour les projets Symfony nécessitant un système d’administration intégré, sans que celui-ci ne soit un produit à part entière. Voyons ensemble les raisons de ce choix.
À la fin de ce billet, vous aurez un /admin fonctionnel, un DashboardController propre, et une compréhension claire de ce qui distingue EasyAdmin de ses alternatives.
Pourquoi EasyAdmin plutôt qu'autre chose
Sonata reste la stack la plus complète. Multi-bundles, multi-bases, gestion fine des permissions, historique de modifications, médiathèque intégrée. Le coût d'entrée est aussi le plus élevé : configuration YAML dense, courbe d'apprentissage longue, et la perception d'avoir installé un mini-CMS pour gérer trois entités.
API Platform Admin s'est imposée pour les projets qui ont déjà une API. Le back-office est généré à partir du schéma OpenAPI/Hydra, en React (Material UI). C'est puissant, mais ça suppose que l'API existe et que vous acceptiez de quitter Twig pour l'admin.
Coder à la main, enfin. Choix raisonnable quand le périmètre tient sur cinq écrans personnalisés et qu'aucune entité ne mérite de CRUD générique.
EasyAdmin se loge dans un créneau précis : vous avez 2 à 30 entités Doctrine à administrer, vous voulez un CRUD générique avec quelques personnalisations, et vous ne voulez pas que le back-office devienne lui-même un projet. C'est exactement le cas de ce blog, qui administre Post, Page, Category, User, RedirectRule, plus une médiathèque, et où l'admin pèse environ 2 000 lignes de PHP — soit 5 % du code applicatif. Autrement dit : un coût d'entretien marginal pour une UI quotidienne.
L'arbitrage tient en une phrase : si l'admin est un produit, regardez Sonata ou un front custom. Si l'admin est un outil, EasyAdmin est probablement le bon choix.
Installation : la commande qui suffit
composer require easycorp/easyadmin-bundleUne seule ligne. Symfony Flex enregistre le bundle, crée le fichier config/packages/easy_admin.yaml minimal, et installe les routes. À ce stade, rien n'est encore visible — il manque un DashboardController, qui est le point d'entrée obligatoire.
bin/console make:admin:dashboardLa commande pose deux questions : le nom de la classe (par défaut DashboardController) et le namespace (par défaut App\Controller\Admin). Acceptez les deux.
Le fichier généré ressemble à ceci, à quelques détails près :
<?php
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminDashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[AdminDashboard(routePath: '/admin', routeName: 'admin')]
class DashboardController extends AbstractDashboardController
{
public function index(): Response
{
return parent::index();
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('Mon Application');
}
}Les attributs prennent le relais
Si vous arrivez d'EasyAdmin v3, deux choses sautent aux yeux dans le code généré.
#[AdminDashboard] au lieu de configureUserMenu() partiel. L'attribut, déclare le routage du dashboard de façon déclarative. Avant, on combinait une route Symfony classique avec une convention de méthode index(). C'est plus clair, plus lisible, et ça permet à EasyAdmin de découvrir vos dashboards (pluriel, on y revient) sans heuristique.
#[AdminRoute] pour les actions custom. Quand vous ajouterez plus tard une action métier, vous l'annoterez avec #[AdminRoute] plutôt qu'avec #[Route]. La différence est subtile mais structurante : l'attribut EasyAdmin déclenche les hooks d'authentification, de contexte (AdminContext) et de sécurité du bundle. Un #[Route] classique sur une méthode de CrudController fonctionne aussi, mais vous perdez le contexte enrichi et la cohérence URL.
Plusieurs dashboards simultanés. Ce point passe inaperçu dans la doc d'install mais devient utile sur les projets multi-rôles. Vous pouvez avoir un AdminDashboardController pour les administrateurs et un EditorDashboardController pour les rédacteurs, chacun avec son menu et ses CRUD autorisés. Inutile à l'installation, bon à savoir avant de structurer les permissions.
AssetMapper par défaut. À l'install, EasyAdmin enregistre ses assets via le composant Symfony AssetMapper — pas via Webpack Encore. Si vous êtes sur un projet Encore historique, les deux cohabitent sans conflit, mais le bundle ne dépendra plus jamais de votre package.json. C'est un choix qui simplifie énormément l'install : pas de npm install, pas de build à lancer pour voir le dashboard.
Sécuriser l'accès dès la première minute
Le piège classique : se réjouir du dashboard, oublier qu'il est ouvert à toute personne connaissant l'URL. EasyAdmin ne pose aucune sécurité par défaut. C'est à vous de la mettre.
Deux étapes. D'abord, déclarer un firewall et un access_control sur /admin dans config/packages/security.yaml :
security:
firewalls:
admin:
pattern: ^/admin
lazy: true
provider: app_user_provider
form_login:
login_path: admin_login
check_path: admin_login
access_control:
- { path: ^/admin/login, roles: PUBLIC_ACCESS }
- { path: ^/admin, roles: ROLE_ADMIN }Ensuite, protéger le DashboardController au niveau code, ceinture et bretelles :
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_ADMIN')]
#[AdminDashboard(routePath: '/admin', routeName: 'admin')]
final class DashboardController extends AbstractDashboardController
{
// ...
}L'attribut #[IsGranted] au niveau classe est redondant avec l'access_control mais s'exécute dans le contrôleur, donc protège même si quelqu'un casse la conf YAML par erreur. Pour un back-office, deux lignes de défense valent mieux qu'une.
Configurer le dashboard
Le DashboardController accepte plusieurs méthodes de configuration. Trois suffisent à ce stade.
configureDashboard() définit le titre, le favicon, les paramètres globaux. C'est la signature visible de l'admin :
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('Lecodeestdanslepre')
;
}index(), enfin, est le rendu de la page d'accueil de l'admin. Par défaut, EasyAdmin redirige vers le premier item du menu.
#[\Override]
public function index(): Response
{
return $this->render('admin/dashboard.html.twig');
}À ce stade, créez un template minimal templates/admin/dashboard.html.twig qui étend @EasyAdmin/page/content.html.twig et rendez-y un message d'accueil. Les widgets viendront plus tard.
Et après ? Les décisions qu'on prend dès maintenant
Vous avez un dashboard fonctionnel, sécurisé, avec un titre. C'est l'instant de prendre trois décisions qui vont structurer toute la suite.
- Une convention de nommage pour les CrudControllers. Le projet utilise
App\Controller\Admin\Crud\pour les CRUD etApp\Controller\Admin\Action\pour les actions custom. C'est arbitraire mais ça paye à la dixième entité — vous savez où chercher sans réfléchir. Toute autre convention vaut mieux que pas de convention. - Une stratégie de découpage des champs. EasyAdmin permet d'écrire
configureFields()comme un mur de 200 lignes ou comme un orchestrateur de cinq méthodes protégées. Le second choix devient évident à la troisième entité ; faites-le dès la première. - Une politique de surcharge des templates. EasyAdmin permet
overrideTemplate('crud/edit', '...')au niveau CRUD. Décidez tôt si vous voulez surcharger globalement (template Twig partagé) ou par entité (template par CRUD).
Aucune de ces décisions n'est gravée dans le marbre. Toutes deviennent coûteuses à revenir une fois qu'on a accumulé six CrudControllers.
Le mot de la fin
L'installation d'EasyAdmin tient en trois commandes. Le piège n'est pas là — il est dans les vingt minutes qui suivent, où on est tenté soit de bricoler vite parce que « ça marche déjà », soit de surcharger tout par anticipation parce que « on en aura besoin ». Les deux extrêmes coûtent cher à six mois.
Le bon réflexe est intermédiaire : firewall sécurisé, conventions de nommage choisies, templates de surcharge prévus, et c'est tout. Pas de CRUD encore, pas de menu encore, pas de personnalisation. Le billet suivant décortiquera la construction d'un menu admin qui tient sur la durée.
Cet article vous a-t-il aidé ?
Vos réactions ne sont pas encore enregistrées — bientôt disponible.