> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Enregistrement et cache des routes d'un package

> À partir de l'implémentation de Laravel 13, découvrez le rôle de loadRoutesFrom, la séparation des middlewares et des noms, ainsi que la procédure pour répercuter les changements de configuration dans le cache des routes.

Lorsqu'un package fournit des endpoints HTTP, il ne suffit pas que ses routes fonctionnent en environnement de développement : elles doivent continuer à respecter le même contrat après que l'application qui les utilise a créé son cache des routes. Si la conception permet de modifier le préfixe d'URL ou l'activation des routes par la configuration, il faut aussi indiquer aux utilisateurs à quel moment ces changements sont pris en compte.

Cette page part des [bases du développement de packages](/fr/advanced/package-development) et traite séparément l'enregistrement et le cycle de vie du cache. La documentation officielle citée est celle de la branche par défaut de Laravel 13, `13.x`, et l'implémentation du framework correspond à la dernière version, `v13.34.0`.

## loadRoutesFrom se contente de charger un fichier

`ServiceProvider::loadRoutesFrom()` ne charge pas le fichier de routes lorsque l'application implémente `CachesRoutes` et que `routesAreCached()` renvoie vrai. Dans les autres cas, le fichier indiqué est chargé avec `require`.

Cette méthode n'ajoute elle-même ni préfixe d'URI ou de nom de route, ni namespace de contrôleur, ni middleware. Elle ne publie pas non plus de fichier et n'ajoute pas de routes à un cache existant.

```mermaid theme={null}
flowchart TD
    A["boot du provider"] --> B["Appel de loadRoutesFrom"]
    B --> C{"Un cache des routes existe ?"}
    C -->|Non| D["require du fichier de routes du package"]
    C -->|Oui| E["Chargement du fichier du package ignoré"]
    E --> F["Le RouteServiceProvider de Laravel<br>charge le cache de l'application"]
```

Le diagramme suppose une application Laravel standard. Il n'existe pas de cache propre au package : les routes du package sont incluses dans le cache des routes de l'ensemble de l'application.

<Warning>
  Nommer le fichier du package `routes/web.php` ne suffit pas à lui appliquer le middleware `web`. Son chemin de chargement diffère de celui des fichiers de routes standard de l'application : déclarez donc explicitement côté package les middlewares nécessaires.
</Warning>

## Séparer la configuration et l'enregistrement

Dans l'exemple suivant, le package crée un endpoint public qui indique s'il est en mesure de répondre. On suppose que le PSR-4 de Composer associe `Acme\Courier\` à `src/` et que le provider est enregistré par [découverte automatique](/fr/advanced/package-discovery) ou manuellement.

```php config/courier.php theme={null}
<?php

return [
    'routes' => [
        'enabled' => true,
        'prefix' => 'acme-courier',
    ],
];
```

La fusion de la configuration se fait dans `register()` et le chargement des routes dans `boot()`. Ne faites pas d'un provider qui enregistre des routes HTTP un `DeferrableProvider` : rien ne garantirait plus que le provider soit démarré au moment où les routes sont nécessaires.

```php src/CourierServiceProvider.php theme={null}
<?php

namespace Acme\Courier;

use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->mergeConfigFrom(__DIR__.'/../config/courier.php', 'courier');
    }

    public function boot(): void
    {
        if (config('courier.routes.enabled')) {
            $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
        }
    }
}
```

Cette condition ne contrôle que l'enregistrement des routes. Si le provider enregistre aussi d'autres services ou des vues, ne les placez pas à l'intérieur de cette condition. Pour la publication de la configuration auprès des utilisateurs et les précautions liées à la fusion de configurations imbriquées, consultez [Fusion et cache de la configuration des packages](/fr/advanced/package-config-merging).

```php routes/web.php theme={null}
<?php

use Acme\Courier\Http\Controllers\StatusController;
use Illuminate\Support\Facades\Route;

Route::middleware('web')
    ->prefix(config('courier.routes.prefix'))
    ->name('acme-courier.')
    ->group(function () {
        Route::get('/status', StatusController::class)->name('status');
    });
```

```php src/Http/Controllers/StatusController.php theme={null}
<?php

namespace Acme\Courier\Http\Controllers;

use Illuminate\Http\JsonResponse;

class StatusController
{
    public function __invoke(): JsonResponse
    {
        return response()->json(['available' => true]);
    }
}
```

L'URI par défaut est `/acme-courier/status` et le nom de route `acme-courier.status`. Si les URL sont générées avec `route('acme-courier.status')`, le code appelant peut conserver le même nom de route même lorsque le préfixe d'URI change. Le `name()` du groupe concatène les chaînes telles quelles : indiquez donc aussi le `.` final.

<Info>
  `web` ne remplace ni l'authentification ni l'autorisation. Cet exemple est un endpoint public qui ne contient aucune information sensible. Pour les endpoints qui renvoient des données utilisateur, prévoyez séparément un middleware d'authentification et un traitement d'autorisation adaptés aux spécifications.
</Info>

## Prévenir séparément les conflits d'URI et de noms de route

Le préfixe d'URI et le préfixe de nom de route sont deux mécanismes distincts. Ajouter l'un ne suffit pas à éviter les conflits de l'autre.

| Élément | Conception dans cet exemple | Point d'attention pour la maintenance |
| - | - | - |
| URI | `acme-courier` par défaut, modifiable par la configuration | Choisir une valeur qui n'entre pas en conflit avec les URL existantes de l'application |
| Nom de route | `acme-courier.` fixe | Utiliser un nom propre au package et le maintenir comme contrat de génération d'URL |
| Contrôleur | Référence de classe | Ne pas dépendre du namespace des contrôleurs de l'application |
| Middleware | `web` explicite | Vérifier la cohérence avec la configuration des middlewares de l'application cible |

Lorsqu'il construit la collection de routes destinée au cache, `AbstractRouteCollection` lève une `LogicException` si une autre route porte déjà le même nom. Le fait que les URL puissent être générées lors d'un démarrage normal ne garantit donc pas que les routes puissent être mises en cache. Deux routes aux URI différentes posent problème si elles portent le même nom.

Ne faites pas de l'écrasement des routes de l'application par l'ordre d'enregistrement un moyen d'étendre votre package. Si nécessaire, fournissez un paramètre permettant de désactiver les routes ainsi qu'un service que les utilisateurs peuvent appeler depuis leurs propres routes.

## La configuration au moment de la création du cache reste dans les définitions de routes

`RouteCacheCommand` exécute d'abord `route:clear`, puis démarre une nouvelle application pour collecter les routes. Il prépare ces routes sous une forme sérialisable et écrit le résultat compilé dans le fichier de cache.

Le fichier de routes du package est lui aussi chargé à ce moment, si bien que le préfixe et l'enregistrement ou non des routes sont déterminés par **la configuration au moment de la création du cache**. Lors des démarrages suivants, `loadRoutesFrom()` ne charge pas le fichier et ce sont les routes en cache qui sont utilisées.

| Changement | Si l'ancien cache des routes reste en place | Action nécessaire |
| - | - | - |
| Ajout d'une route dans le package | La route ajoutée n'apparaît pas | Recréer le cache des routes |
| Modification de `routes.prefix` | L'ancienne URI reste en place | Recréer le cache avec la nouvelle configuration |
| Passage de `routes.enabled` à `false` | Les routes présentes dans le cache ne disparaissent pas | Recréer le cache avec la configuration désactivée |
| Suppression du package | Des définitions référençant des classes supprimées peuvent subsister | Recréer le cache avec la configuration après suppression |

<Warning>
  `routes.enabled` est un paramètre qui contrôle l'enregistrement, et non un refus d'accès à chaque requête. Désactiver uniquement le paramètre alors qu'un ancien cache reste en place ne revient pas à arrêter l'endpoint.
</Warning>

N'enregistrez pas de routes selon des conditions qui varient à chaque requête, comme l'utilisateur ou le tenant. Ces conditions seraient évaluées dans l'environnement CLI au moment de la création du cache. Enregistrez les routes avec une configuration stable et déterminez l'autorisation d'accès via un middleware ou une vérification d'autorisation dans le contrôleur.

### Figer la configuration en premier lors du déploiement

Une fois le code et la configuration mis à jour, si votre environnement utilise le cache de configuration, recréez les caches dans l'ordre suivant. Intégrez ces étapes au processus de déploiement de l'application.

```bash theme={null}
php artisan config:cache
php artisan route:cache
php artisan route:list --name=acme-courier -vv
```

Si vous exécutez `route:cache` alors qu'un ancien cache de configuration est encore présent, les routes sont elles aussi construites avec l'ancienne configuration. Réexécuter uniquement `config:cache` ne met pas à jour le cache des routes. L'option `-vv` permet aussi de vérifier le contenu des groupes de middlewares.

Pour vérifier le comportement sans cache pendant le développement, videz les deux caches si nécessaire.

```bash theme={null}
php artisan config:clear
php artisan route:clear
```

Le fichier de routes n'est pas exécuté lors d'un démarrage avec cache. Y enregistrer des écouteurs d'événements ou des liaisons du conteneur modifierait donc le comportement : évitez tout effet de bord autre que la définition des routes. Dans les environnements qui utilisent des processus de longue durée, incluez aussi leur rechargement après la mise à jour du cache dans la procédure de déploiement habituelle.

## Combinaisons à vérifier avant une publication

En plus des tests du package, vérifiez les combinaisons suivantes dans une application Laravel 13 qui l'utilise. Ne vous limitez pas à l'enregistrement des routes en mémoire : couvrez aussi le chemin par lequel Artisan démarre une nouvelle application.

* Sans cache, `/acme-courier/status` répond, et le nom de route et les middlewares sont ceux attendus.
* `route:cache` réussit et, lors d'un nouveau démarrage, la réponse arrive avec la même URI et le même nom de route.
* Après modification du préfixe et recréation du cache, la nouvelle URI répond et la route du package à l'ancienne URI disparaît.
* Après désactivation et recréation du cache, les routes concernées n'apparaissent pas dans `route:list --name=acme-courier`.
* Les URI et noms de route n'entrent pas en conflit avec ceux de l'application ou d'autres packages.

En vérifiant aussi le cas où l'ancien cache reste en place, vous pourrez reproduire les signalements du type « j'ai modifié le fichier de configuration mais l'URL ne change pas ». Mentionnez explicitement la recréation du cache dans la procédure de mise à niveau, et considérez aussi les changements de noms de route et de middlewares comme des questions de compatibilité.

## Pages associées

<Columns cols={2}>
  <Card title="Routage" icon="route" href="/fr/routing">
    Les bases des groupes de routes, des routes nommées et de l'affichage de la liste des routes.
  </Card>

  <Card title="Fusion et cache de la configuration des packages" icon="sliders" href="/fr/advanced/package-config-merging">
    La procédure de mise à jour qui tient compte de la configuration publiée et du cache de configuration.
  </Card>

  <Card title="Service providers différés" icon="clock" href="/fr/advanced/deferred-provider">
    Pourquoi il ne faut pas différer un provider qui enregistre des routes.
  </Card>

  <Card title="Gestion de la compatibilité de versions de package" icon="code-branch" href="/fr/advanced/package-versioning">
    Relier les changements d'API publique à votre politique de publication et à la vérification continue.
  </Card>
</Columns>

## Sources primaires consultées

* [Documentation officielle de Laravel : routes des packages](https://github.com/laravel/docs/blob/156fc7fde114548640e13c39aa79b991291c3f91/packages.md#routes)
* [Documentation officielle de Laravel : routage](https://github.com/laravel/docs/blob/156fc7fde114548640e13c39aa79b991291c3f91/routing.md)
* [ServiceProvider : implémentation de loadRoutesFrom](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Support/ServiceProvider.php)
* [RouteServiceProvider : chargement du cache](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php)
* [RouteCacheCommand : collecte dans une nouvelle application et enregistrement](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Console/RouteCacheCommand.php)
* [AbstractRouteCollection : détection des noms de route en double](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Routing/AbstractRouteCollection.php)


## Related topics

- [Développement de packages Laravel](/fr/advanced/package-development.md)
- [Sujets avancés](/fr/advanced/index.md)
- [Surcharger et mettre à jour les vues d'un package](/fr/advanced/package-views.md)
- [Publier et mettre à jour les migrations d'un package](/fr/advanced/package-migrations.md)
- [Fusion et cache de la configuration des packages](/fr/advanced/package-config-merging.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.