Laravel Débutant

Comment gérer les routes sur Laravel

Fini le fourre-tout: séparez vos routes Laravel par domaine avec prefix() et name() pour des URLs claires et des fichiers web/api minimalistes.

3 min de lecture

Organiser vos routes Laravel dans des fichiers séparés, propres et lisibles

Dans un projet Laravel qui grandit, le fichier routes/web.php ou routes/api.php devient vite un fourre-tout illisible. Vous scrollez sans fin, vous avez du mal à retrouver une route, vous dupliquez des préfixes et des noms… bref, ce n’est ni efficace ni maintenable.

La bonne nouvelle : Laravel permet de séparer vos routes dans plusieurs fichiers, tout en gardant des prefix et des namespaces de nom de route clairs. Résultat : des routes bien rangées, accessibles, lisibles et non redondantes.

Dans cet article, vous allez voir comment :

  • Structurer vos fichiers de routes par domaine fonctionnel
  • Utiliser les prefix et names intelligemment
  • Garder web.php (ou api.php) minimal et clair
  • Générer des URLs et des redirections avec des noms de route expressifs

Pourquoi séparer vos routes ?

Quand vous commencez, tout mettre dans web.php ou api.php semble suffisant. Mais rapidement, vous accumulez :

  • Des routes pour les utilisateurs
  • Des routes pour la facturation
  • Des routes pour l’administration
  • Des routes pour le blog, etc.

Sans organisation, vous obtenez :

  • Un fichier de 500+ lignes difficile à lire
  • Des prefix répétés partout (/admin, /api/users…)
  • Des noms de route incohérents ou en doublon

L’idée est donc de :

  • Créer un fichier de routes par “domaine” (user, billing, admin…)
  • Centraliser les groupes, prefix et names dans le fichier principal
  • Ne mettre que des Route::get(...), Route::post(...), etc. dans les fichiers secondaires

Structure de base : un groupe global + des fichiers inclus

Prenons un exemple avec une API. Dans votre fichier routes/api.php, vous pouvez regrouper tout ce qui concerne l’API sous un name global api. :

<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Route;

Route::name('api.')
    ->prefix('v1')
    ->group(function (): void {
        require __DIR__ . '/api/user.php';
        require __DIR__ . '/api/exercise.php';
        require __DIR__ . '/api/program.php';
        require __DIR__ . '/api/billing.php';
    });

Ici :

  • Toutes les routes auront un nom qui commence par api. (ex: api.user.index)
  • Toutes les URLs seront préfixées par /v1 (ex: /api/v1/users)
  • Le fichier api.php reste court et lisible

Ensuite, chaque fichier inclus gère un domaine précis. Voyons un exemple concret avec routes/api/user.php.

Exemple complet : routes API utilisateur

Créez le fichier routes/api/user.php :

<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\UserController;

Route::prefix('users')
    ->name('user.')
    ->group(function (): void {
        Route::get('/', [UserController::class, 'index'])
            ->name('index'); // api.user.index

        Route::get('/{user}', [UserController::class, 'show'])
            ->name('show'); // api.user.show

        Route::post('/', [UserController::class, 'store'])
            ->name('store'); // api.user.store

        Route::put('/{user}', [UserController::class, 'update'])
            ->name('update'); // api.user.update

        Route::delete('/{user}', [UserController::class, 'destroy'])
            ->name('destroy'); // api.user.destroy
    });

Grâce au group global de api.php :

  • URL de index : /api/v1/users
  • Nom complet de la route : api.user.index

Vous obtenez une hiérarchie lisible :

  • api.user.index
  • api.user.show
  • api.user.store
  • api.user.update
  • api.user.destroy

Ce schéma se répète pour chaque domaine : exercise.php, program.php, billing.php, etc.

Exemple pour la facturation : routes/api/billing.php

<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\BillingController;

Route::prefix('billing')
    ->name('billing.')
    ->group(function (): void {
        Route::get('/subscriptions', [BillingController::class, 'subscriptions'])
            ->name('subscriptions'); // api.billing.subscriptions

        Route::post('/checkout', [BillingController::class, 'checkout'])
            ->name('checkout'); // api.billing.checkout
    });

Toujours le même principe :

  • URL : /api/v1/billing/subscriptions
  • Nom : api.billing.subscriptions

Faire la même chose côté web.php

Vous pouvez appliquer exactement la même logique à vos routes web. Imaginez un site avec :

  • Une partie publique (home, blog, contact)
  • Une partie admin protégée

Dans routes/web.php :

<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Route;

Route::name('web.')
    ->group(function (): void {
        require __DIR__ . '/web/public.php';
        require __DIR__ . '/web/admin.php';
    });

Routes publiques : routes/web/public.php

<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\BlogController;
use App\Http\Controllers\ContactController;

Route::get('/', [HomeController::class, 'index'])
    ->name('home'); // web.home

Route::get('/blog', [BlogController::class, 'index'])
    ->name('blog.index'); // web.blog.index

Route::get('/blog/{slug}', [BlogController::class, 'show'])
    ->name('blog.show'); // web.blog.show

Route::get('/contact', [ContactController::class, 'form'])
    ->name('contact.form'); // web.contact.form

Route::post('/contact', [ContactController::class, 'submit'])
    ->name('contact.submit'); // web.contact.submit

Routes admin : routes/web/admin.php

<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\DashboardController;
use App\Http\Controllers\Admin\UserController as AdminUserController;

Route::prefix('admin')
    ->name('admin.')
    ->middleware(['auth', 'can:access-admin'])
    ->group(function (): void {
        Route::get('/', [DashboardController::class, 'index'])
            ->name('dashboard'); // web.admin.dashboard

        Route::get('/users', [AdminUserController::class, 'index'])
            ->name('users.index'); // web.admin.users.index
    });

Vous avez maintenant :

  • Des routes publiques du type web.home, web.blog.show
  • Des routes admin du type web.admin.dashboard, web.admin.users.index
  • Une séparation claire des responsabilités

Utiliser les noms de route au quotidien

Avec cette organisation, utiliser les routes dans vos vues et contrôleurs devient très lisible.

Dans les vues Blade

<a href="{{ route('web.blog.index') }}">
    Voir le blog
</a>

<a href="{{ route('web.admin.dashboard') }}">
    Admin
</a>

Dans les contrôleurs PHP

<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;

final class ContactController
{
    public function submit(): RedirectResponse
    {
        // Traitement du formulaire...

        return redirect()
            ->route('web.contact.form')
            ->with('status', 'Message envoyé avec succès.');
    }
}

Les noms de route expriment la hiérarchie :

  • web.contact.form
  • web.admin.users.index
  • api.user.show

Vous savez immédiatement à quelle zone de l’application ils appartiennent.

Bonnes pratiques pour garder vos routes “bien rangées”

  • Un domaine fonctionnel = un fichierExemple : user.php, billing.php, chat.php, etc.
  • Préfixez toujours les groupes de routes (URL et noms) Utilisez prefix() pour les URLs et name() pour les noms.
  • Pas de logique métier dans les fichiers de routesUniquement des déclarations de routes. La logique va dans les contrôleurs.
  • Respectez une convention claire pour les noms Par exemple : {scope}.{resource}.{action}web.admin.users.index, api.user.store.
  • Gardez api.php / web.php minimalIdéalement : uniquement des groupes globaux + des require.

Une API (ou un web) propre commence par des routes bien structurées

Séparer vos routes dans des fichiers dédiés, avec des prefix et des namespaces de noms cohérents, vous apporte :

  • Un code plus lisible et navigable
  • Moins de redondance dans les préfixes
  • Des noms de route clairs et stables pour vos vues et contrôleurs
  • Une base solide pour faire évoluer votre projet sans chaos

Retenez ces points clés :

  1. Utilisez un groupe global dans web.php / api.php avec name() (et éventuellement prefix()).
  2. Créez un fichier de routes par domaine (user, billing, admin…).
  3. Dans chaque fichier, utilisez un groupe local avec son propre prefix() et name().
  4. Exploitez pleinement les noms de route pour vos URLs et redirections.

En appliquant cette structure, vos routes Laravel deviennent un vrai plan de l’application plutôt qu’une simple liste d’URLs. Et surtout, vous n’avez plus peur d’ouvrir vos fichiers de routes.

Contact

Travaillons ensemble

Vous avez un projet en tête ? Remplissez le formulaire et je vous répondrai dans les plus brefs délais.