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

# Paket-Routen registrieren und cachen

> Anhand der Implementierung von Laravel 13 erläutert: die Rolle von loadRoutesFrom, die Trennung von Middleware und Namen sowie die Schritte, mit denen Konfigurationsänderungen im Route-Cache ankommen.

Wenn ein Paket HTTP-Endpunkte bereitstellt, reicht es nicht, dass die Routen in der Entwicklungsumgebung funktionieren. Sie müssen auch dann nach derselben Vereinbarung funktionieren, wenn die nutzende Anwendung einen Route-Cache erstellt hat. Lassen sich das URL-Präfix oder das Aktivieren und Deaktivieren über die Konfiguration ändern, sollten Sie den Nutzern auch erklären, wann diese Änderungen wirksam werden.

Diese Seite setzt die [Grundlagen der Paketentwicklung](/de/advanced/package-development) voraus und betrachtet die Registrierung und den Lebenszyklus des Caches getrennt voneinander. Als Referenz dienen die offizielle Dokumentation zu Laravel 13 im Standard-Branch `13.x` und für die Framework-Implementierung das aktuelle Release `v13.34.0`.

## loadRoutesFrom lädt nur die Datei

`ServiceProvider::loadRoutesFrom()` lädt die Route-Datei nicht, wenn die Anwendung `CachesRoutes` implementiert und `routesAreCached()` true zurückgibt. In allen anderen Fällen wird die angegebene Datei per `require` eingebunden.

Die Methode selbst fügt weder ein Präfix für URIs oder Routennamen noch einen Controller-Namespace oder Middleware hinzu. Sie veröffentlicht auch keine Dateien und ergänzt keine Routen in einem bestehenden Cache.

```mermaid theme={null}
flowchart TD
    A["boot des Providers"] --> B["loadRoutesFrom aufrufen"]
    B --> C{"Route-Cache vorhanden?"}
    C -->|Nein| D["Route-Datei des Pakets per require laden"]
    C -->|Ja| E["Laden der Paketdatei überspringen"]
    E --> F["RouteServiceProvider von Laravel<br>lädt den Cache der Anwendung"]
```

Das Diagramm geht von einer Standard-Laravel-Anwendung aus. Es gibt keinen eigenen Cache für das Paket. Die Routen des Pakets sind im Route-Cache der gesamten Anwendung enthalten.

<Warning>
  Auch wenn die Datei im Paket `routes/web.php` heißt, erhält sie dadurch allein nicht die Middleware `web`. Sie wird auf einem anderen Weg geladen als die Standard-Route-Dateien der Anwendung. Geben Sie die benötigte Middleware daher im Paket explizit an.
</Warning>

## Konfiguration und Registrierung trennen

Im folgenden Beispiel erstellen wir einen öffentlichen Endpunkt, der meldet, ob das Paket antwortbereit ist. Vorausgesetzt wird, dass `Acme\Courier\` per PSR-4 in Composer auf `src/` abgebildet ist und der Provider über die [automatische Erkennung](/de/advanced/package-discovery) oder manuell registriert wird.

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

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

Die Konfiguration führen Sie in `register()` zusammen, die Routen laden Sie in `boot()`. Machen Sie einen Provider, der HTTP-Routen registriert, nicht zu einem `DeferrableProvider`. Sonst ist nicht garantiert, dass der Provider gestartet ist, wenn die Routen gebraucht werden.

```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');
        }
    }
}
```

Diese Bedingung steuert nur die Registrierung der Routen. Registriert der Provider auch andere Services oder Views, gehören diese nicht in den Block der Bedingung. Wie Sie die Konfiguration für Nutzer veröffentlichen und was beim Zusammenführen verschachtelter Konfigurationen zu beachten ist, lesen Sie unter [Paketkonfiguration zusammenführen und cachen](/de/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]);
    }
}
```

Die Standard-URI lautet `/acme-courier/status`, der Routenname `acme-courier.status`. Wenn Sie URLs mit `route('acme-courier.status')` erzeugen, kann der aufrufende Code denselben Routennamen verwenden, auch wenn sich das URI-Präfix ändert. `name()` einer Gruppe verkettet die Zeichenketten unverändert, deshalb geben Sie auch den abschließenden `.` an.

<Info>
  `web` ersetzt keine Authentifizierung oder Autorisierung. Dieses Beispiel ist ein öffentlicher Endpunkt ohne vertrauliche Daten. Für Endpunkte, die Daten von Nutzern zurückgeben, sehen Sie zusätzlich eine passende Authentifizierungs-Middleware und Autorisierungsprüfungen vor.
</Info>

## Kollisionen bei URIs und Routennamen getrennt vermeiden

Das URI-Präfix und das Präfix für Routennamen sind zwei verschiedene Mechanismen. Wenn Sie nur eines davon setzen, verhindern Sie keine Kollisionen beim anderen.

| Gegenstand | Entwurf in diesem Beispiel | Hinweis zur Pflege |
| - | - | - |
| URI | Standardwert `acme-courier`, über die Konfiguration änderbar | Einen Wert wählen, der nicht mit bestehenden URLs der nutzenden Anwendung kollidiert |
| Routenname | `acme-courier.` fest vorgegeben | Einen paketspezifischen Namen verwenden und als Vereinbarung für die URL-Erzeugung beibehalten |
| Controller | Klassenreferenz verwenden | Nicht vom Controller-Namespace der Anwendung abhängig machen |
| Middleware | `web` explizit angeben | Mit der Middleware-Konfiguration der Zielanwendung abgleichen |

`AbstractRouteCollection` wirft beim Erstellen der Routensammlung für den Cache eine `LogicException`, wenn eine andere Route bereits denselben Namen trägt. Dass sich URLs beim normalen Start erzeugen ließen, garantiert also nicht, dass sich die Routen cachen lassen. Auch zwei Routen mit unterschiedlichen URIs verursachen ein Problem, wenn sie denselben Namen haben.

Machen Sie das Überschreiben von Routen der nutzenden Anwendung über die Registrierungsreihenfolge nicht zum Erweiterungsweg Ihres Pakets. Stellen Sie bei Bedarf eine Einstellung zum Deaktivieren der Routen sowie einen Service bereit, den Nutzer aus eigenen Routen aufrufen können.

## Die Konfiguration zum Zeitpunkt der Cache-Erstellung bleibt in den Routendefinitionen

`RouteCacheCommand` führt zuerst `route:clear` aus, startet dann eine neue Anwendung und sammelt die Routen. Diese Routen werden für die Serialisierung vorbereitet, und das kompilierte Ergebnis wird in die Cache-Datei geschrieben.

Dabei wird auch die Route-Datei des Pakets geladen. Präfix und Registrierung richten sich daher nach der **Konfiguration zum Zeitpunkt der Cache-Erstellung**. Bei späteren Starts lädt `loadRoutesFrom()` die Datei nicht mehr, und es werden die gecachten Routen verwendet.

| Änderung | Wenn ein alter Route-Cache bestehen bleibt | Erforderliche Maßnahme |
| - | - | - |
| Route im Paket hinzugefügt | Die neue Route erscheint nicht | Route-Cache neu erstellen |
| `routes.prefix` geändert | Die alte URI bleibt bestehen | Mit der neuen Konfiguration neu erstellen |
| `routes.enabled` auf `false` gesetzt | Routen im Cache verschwinden nicht | Mit der deaktivierenden Konfiguration neu erstellen |
| Paket entfernt | Definitionen, die auf gelöschte Klassen verweisen, können bestehen bleiben | Mit der Konfiguration nach dem Entfernen neu erstellen |

<Warning>
  `routes.enabled` steuert die Registrierung und ist keine Zugriffssperre pro Anfrage. Wenn Sie nur die Einstellung deaktivieren, während ein alter Cache bestehen bleibt, ist der Endpunkt damit nicht abgeschaltet.
</Warning>

Registrieren Sie Routen nicht abhängig von Bedingungen, die sich pro Anfrage ändern, etwa Benutzer oder Mandanten. Solche Bedingungen werden in der CLI-Umgebung ausgewertet, in der der Cache erstellt wird. Registrieren Sie Routen mit einer stabilen Konfiguration und entscheiden Sie über den Zugriff mit Middleware oder einer Autorisierung im Controller.

### Beim Deployment zuerst die Konfiguration festlegen

Wenn Code und Konfiguration aktualisiert sind, erstellen Sie die Caches in Setups mit Konfigurations-Cache in der folgenden Reihenfolge neu. Nehmen Sie diese Schritte in den Deployment-Prozess der nutzenden Anwendung auf.

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

Führen Sie `route:cache` aus, während ein alter Konfigurations-Cache besteht, werden auch die Routen mit der alten Konfiguration erstellt. Wenn Sie nur `config:cache` erneut ausführen, wird der Route-Cache nicht aktualisiert. Mit `-vv` sehen Sie auch den Inhalt der Middleware-Gruppen.

Um das Verhalten während der Entwicklung ohne Cache zu prüfen, leeren Sie bei Bedarf beide Caches.

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

Bei einem Start mit Cache wird die Route-Datei nicht ausgeführt. Registrieren Sie dort Event-Listener oder Container-Bindings, ändert sich das Verhalten. Geben Sie der Route-Datei daher keine Nebenwirkungen außer den Routendefinitionen. In Umgebungen mit langlebigen Prozessen gehört auch das Neuladen nach einer Cache-Aktualisierung zum normalen Deployment-Ablauf.

## Kombinationen, die Sie vor einem Release prüfen

Prüfen Sie zusätzlich zu den Tests des Pakets die folgenden Kombinationen in einer nutzenden Laravel-13-Anwendung. Testen Sie nicht nur die Routenregistrierung im Speicher, sondern auch den Weg, auf dem Artisan eine neue Anwendung startet.

* Ohne Cache antwortet `/acme-courier/status`, und Routenname sowie Middleware entsprechen den Erwartungen.
* `route:cache` läuft erfolgreich, und auch nach einem neuen Start antwortet die Route unter derselben URI und demselben Routennamen.
* Nach einer Änderung des Präfixes und dem Neuerstellen des Caches antwortet die neue URI, und unter der alten URI gibt es keine Paketroute mehr.
* Nach dem Deaktivieren und dem Neuerstellen des Caches erscheint die Route nicht in `route:list --name=acme-courier`.
* URIs und Routennamen kollidieren nicht mit der nutzenden Anwendung oder anderen Paketen.

Wenn Sie auch den Fall mit einem verbliebenen alten Cache prüfen, können Sie Meldungen von Nutzern wie „Ich habe die Konfigurationsdatei geändert, aber die URL ändert sich nicht“ nachstellen. Nehmen Sie das Neuerstellen des Caches ausdrücklich in die Upgrade-Anleitung auf, und behandeln Sie auch Änderungen an Routennamen oder Middleware als Frage der Kompatibilität.

## Verwandte Seiten

<Columns cols={2}>
  <Card title="Routing" icon="route" href="/de/routing">
    Grundlagen zu Routengruppen, benannten Routen und der Routenliste.
  </Card>

  <Card title="Paketkonfiguration zusammenführen und cachen" icon="sliders" href="/de/advanced/package-config-merging">
    Update-Schritte, die veröffentlichte Konfigurationen und den Konfigurations-Cache berücksichtigen.
  </Card>

  <Card title="Deferred Service Provider" icon="clock" href="/de/advanced/deferred-provider">
    Warum Provider, die Routen registrieren, nicht verzögert geladen werden sollten.
  </Card>

  <Card title="Versionskompatibilität von Paketen verwalten" icon="code-branch" href="/de/advanced/package-versioning">
    Verknüpfen Sie Änderungen an der öffentlichen API mit Ihrer Release-Strategie und kontinuierlicher Prüfung.
  </Card>
</Columns>

## Herangezogene Primärquellen

* [Offizielle Laravel-Dokumentation: Paket-Routen](https://github.com/laravel/docs/blob/156fc7fde114548640e13c39aa79b991291c3f91/packages.md#routes)
* [Offizielle Laravel-Dokumentation: Routing](https://github.com/laravel/docs/blob/156fc7fde114548640e13c39aa79b991291c3f91/routing.md)
* [ServiceProvider: Implementierung von loadRoutesFrom](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Support/ServiceProvider.php)
* [RouteServiceProvider: Laden des Caches](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php)
* [RouteCacheCommand: Sammeln in einer neuen Anwendung und Speichern](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Console/RouteCacheCommand.php)
* [AbstractRouteCollection: Erkennung doppelter Routennamen](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Routing/AbstractRouteCollection.php)


## Related topics

- [Laravel-Paketentwicklung](/de/advanced/package-development.md)
- [Weiterführende Themen](/de/advanced/index.md)
- [Paketkonfiguration zusammenführen und cachen](/de/advanced/package-config-merging.md)
- [Routen](/de/packages/laravel-bluesky/route.md)
- [Einen MCP-Server mit Laravel bauen](/de/advanced/mcp-server.md)


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