Wenn es um das Backend geht, stoßen Entwickler irgendwann auf Routen. Routen können als das Rückgrat des Backends betrachtet werden, da jede Anfrage, die der Server erhält, über eine Routing-Liste an einen Controller weitergeleitet wird, der die Anfragen den Controllern oder Aktionen zuordnet.

Laravel verbirgt viele Implementierungsdetails für uns und kommt mit einer Menge syntaktischem Zuckerschlecken, um sowohl neuen als auch erfahrenen Entwicklern bei der Entwicklung ihrer Webanwendungen zu helfen.

Schauen wir uns genauer an, wie man Routen in Laravel verwaltet.

Backend-Routing und Cross-Site-Scripting in Laravel

Auf einem Server gibt es sowohl öffentliche als auch private Routen. Öffentliche Routen können Anlass zur Sorge geben, da sie die Möglichkeit für Cross-Site-Scripting (XSS) bieten, eine Art von Injektionsangriff, der dich und deine Nutzer/innen für böswillige Akteure angreifbar machen kann.

Das Problem besteht darin, dass ein Nutzer von einer Route, die kein Sitzungs-Token erfordert, auf eine Route umgeleitet werden kann, die ein solches erfordert – und er auch ohne das Token Zugang hat.

Die einfachste Möglichkeit, dieses Problem zu lösen, besteht darin, einen neuen HTTP-Header zu erzwingen, der der Route „referrer“ hinzufügt, um dieses Szenario zu entschärfen:

'main' => [
  'path' => '/main',
  'referrer' => 'required,refresh-empty',
  'target' => ControllerDashboardController::class . '::mainAction'
]

Laravel Basic Routing

In Laravel ermöglichen es Routen, die entsprechende Anfrage an den gewünschten Controller weiterzuleiten. Die grundlegendste Laravel-Route akzeptiert einen Uniform Asset Identifier (deinen Routenpfad) und eine Closure, die sowohl eine Funktion als auch eine Klasse sein kann.

In Laravel werden die Routen in den Dateien web.php und api.php erstellt. Laravel wird standardmäßig mit zwei Routen ausgeliefert: eine für die WEB und eine für die API.

Diese Routen befinden sich im Ordner routes/, aber sie werden in der Datei Providers/RouteServiceProvider.php geladen.

Eine Befehlszeile, die den Standardstatus des Laravel-Routen-Dienstanbieters anzeigt
Standardzustand des Routen-Service-Providers von Laravel

Stattdessen können wir die Routen auch direkt in RouteServiceProvider.php laden und den Ordner routes/ ganz überspringen.

Eine Befehlszeile, die den Standardstatus des Laravel-Routen-Dienstanbieters anzeigt
Laravel-Routen direkt in den Provider laden

Umleitungen

Wenn wir eine Route definieren, wollen wir den Nutzer, der auf sie zugreift, in der Regel umleiten, und die Gründe dafür sind vielfältig. Das kann daran liegen, dass es sich um eine veraltete Route handelt und wir das Backend oder den Server geändert haben, oder weil wir eine Zwei-Faktor-Authentifizierung (2FA) installieren wollen usw.

Laravel bietet eine einfache Möglichkeit, dies zu tun. Dank der Einfachheit des Frameworks können wir die Redirect-Methode der Route-Fassade verwenden, die die Eingangsroute und die Route, zu der umgeleitet werden soll, akzeptiert.

Optional können wir den Statuscode für die Weiterleitung als dritten Parameter angeben. Die Methode permanentRedirect tut dasselbe wie die Methode redirect, nur dass sie immer einen 301-Statuscode zurückgibt:

// Simple redirect
Route::redirect("/class", "/myClass");

// Redirect with custom status
Route::redirect("/home", "/office", 305);

// Route redirect with 301 status code
Route::permanentRedirect("/home", "office");

Innerhalb der Redirect-Routen dürfen wir die Schlüsselwörter „destination“ und „status“ nicht als Parameter verwenden, da sie von Laravel reserviert sind.

// Illegal to use
Route::redirect("/home", "/office/{status}");

Views

Views sind die .blade.php-Dateien, die wir für die Darstellung des Frontends unserer Laravel-Anwendung verwenden. Sie verwenden die Blade-Templating-Engine und sind die Standardmethode, um eine Full-Stack-Anwendung nur mit Laravel zu erstellen.

Wenn wir wollen, dass unsere Route eine Ansicht zurückgibt, können wir einfach die Methode view der Route-Fassade verwenden. Sie akzeptiert einen Routenparameter, einen View-Namen und ein optionales Array von Werten, die an den View übergeben werden.

// When the user accesses my-domain.com/homepage
// the homepage.blade.php file will be rendered
Route::view("/homepage", "homepage");

Nehmen wir an, unsere View will „Hallo, {name}“ sagen, indem sie ein optionales Array mit diesem Parameter übergibt. Mit dem folgenden Code können wir genau das tun (wenn der fehlende Parameter in der View erforderlich ist, wird die Anfrage fehlschlagen und einen Fehler auslösen):

Route::view('/homepage', 'homepage', ['name' => "Kinsta"]);

Routenliste

Wenn deine Anwendung größer wird, steigt auch die Anzahl der Anfragen, die weitergeleitet werden müssen. Und mit einer großen Menge an Informationen kann auch große Verwirrung entstehen.

Hier kann die artisan route:list command helfen. Sie bietet einen Überblick über alle Routen, die in der Anwendung definiert sind, sowie über die Middlewares und Controller.

php artisan route:list

Es wird eine Liste aller Routen ohne die Middlewares angezeigt. Hierfür müssen wir das -v Flag verwenden:

php artisan route:list -v

Wenn du ein domänengesteuertes Design verwendest, bei dem deine Routen bestimmte Namen in ihren Pfaden haben, kannst du die Filterfunktionen dieses Befehls wie folgt nutzen:

php artisan route:list –path=api/account

So werden nur die Routen angezeigt, die mit api/account beginnen.

Andererseits können wir Laravel mit den Optionen –except-vendor oder –only-vendor anweisen, von Dritten definierte Routen auszuschließen oder einzuschließen.

Routenparameter

Manchmal ist es notwendig, Teile der URI mit der Route zu erfassen, z. B. eine Benutzer-ID oder ein Token. Dies können wir tun, indem wir einen Routenparameter definieren, der immer in geschweifte Klammern ({}) eingeschlossen ist und nur aus alphabetischen Zeichen bestehen sollte.

Wenn unsere Routen Abhängigkeiten in ihren Callbacks haben, wird der Laravel Service Container diese automatisch einbinden:

use IlluminateHttpRequest;
use Controllers/DashboardController;
Route::post('/dashboard/{id}, function (Request $request, string $id) {
  return 'User:' . $id;
}
Route::get('/dashboard/{id}, DashboardController.php);

Erforderliche Parameter

Laravels erforderliche Parameter sind Parameter in Routen, die wir bei einem Aufruf nicht auslassen dürfen. Andernfalls wird ein Fehler ausgelöst:

Route::post("/gdpr/{userId}", GetGdprDataController.php");

In GetGdprDataController.php haben wir nun direkten Zugriff auf den Parameter $userId.

public function __invoke(int $userId) {
  // Use the userId that we received…
}

Eine Route kann eine beliebige Anzahl von Parametern enthalten. Sie werden in der Reihenfolge, in der sie aufgelistet sind, in die Callbacks/Controller der Route injiziert:

 // api.php
Route::post('/gdpr/{userId}/{userName}/{userAge}', GetGdprDataController.php);
// GetGdprDataController.php
public function __invoke(int $userId, string $userName, int $userAge) {
  // Use the parameters…
}

Optionale Parameter

Wenn wir in einer Route etwas verändern wollen, in der nur ein Parameter vorhanden ist und sonst nichts, ohne dass die gesamte Anwendung betroffen ist, können wir einen optionalen Parameter hinzufügen. Diese optionalen Parameter sind an dem angehängten ? zu erkennen:

 Route::get('/user/{age?}', function (int $age = null) {
  if (!$age) Log::info("User doesn't have age set");
  else Log::info("User's age is " . $age);
}
Route::get('/user/{name?}', function (int $name = "John Doe") {
  Log::info("User's name is " . $name);
}

Route Wildcard

Laravel bietet uns eine Möglichkeit, zu filtern, wie unsere optionalen oder erforderlichen Parameter aussehen sollen.

Nehmen wir an, wir wollen einen String mit einer Benutzer-ID. Wir können sie auf der Routenebene mit der Methode where validieren.

Die Methode where akzeptiert den Namen des Parameters und die Regex-Regel, die auf die Validierung angewendet werden soll. Standardmäßig nimmt sie den ersten Parameter, aber wenn wir viele haben, können wir ein Array mit dem Namen des Parameters als Schlüssel und der Regel als Wert übergeben und Laravel wird sie alle für uns analysieren:

Route::get('/user/{age}', function (int $age) {
  //
}->where('age', '[0-9]+');
Route::get('/user/{age}', function (int $age) {
  //
}->where('[0-9]+');
Route::get('/user/{age}/{name}', function (int $age, string $name) {
  //
}->where(['age' => '[0-9]+', 'name' => '[a-z][A-z]+');

Wir können noch einen Schritt weiter gehen und die Validierung auf alle Routen in unserer Anwendung anwenden, indem wir die Methode pattern in der Route -Fassade verwenden:

 Route::pattern('id', '[0-9]+');

Damit wird jeder id Parameter mit diesem Regex-Ausdruck validiert. Und wenn wir ihn einmal definiert haben, wird er automatisch auf alle Routen angewendet, die diesen Parameternamen verwenden.

Wie wir sehen können, verwendet Laravel das Zeichen / als Trennzeichen im Pfad. Wenn wir es im Pfad verwenden wollen, müssen wir es mit einer where Regex explizit als Teil unseres Platzhalters zulassen.

 Route::get('/find/{query}', function ($query) {
  //
})->where('query', , '.*');

Der einzige Nachteil ist, dass es nur im letzten Routensegment unterstützt wird.

Benannte Routen

Wie der Name schon sagt, können wir Routen benennen, um URLs oder Weiterleitungen für bestimmte Routen zu erstellen.

Wie man benannte Routen erstellt

Eine einfache Möglichkeit, eine benannte Route zu erstellen, bietet die name Methode, die auf der Route Fassade verkettet ist. Der Name jeder Route sollte eindeutig sein:

 Route::get('/', function () {
})->name("homepage");

Routengruppen

Routengruppen ermöglichen es dir, Routenattribute wie Middlewares für eine große Anzahl von Routen gemeinsam zu nutzen, ohne sie für jede einzelne Route neu definieren zu müssen.

Middleware

Wenn wir allen Routen eine Middleware zuweisen, können wir sie in einer Gruppe zusammenfassen, indem wir zunächst die Methode group verwenden. Dabei ist zu beachten, dass die Middlewares in der Reihenfolge ausgeführt werden, in der sie auf die Gruppe angewendet werden:

 Route:middleware(['AuthMiddleware', 'SessionMiddleware'])->group(function () {
  Route::get('/', function() {} );
  Route::post('/upload-picture', function () {} );
});

Controller

Wenn eine Gruppe denselben Controller verwendet, können wir mit der Methode controller den gemeinsamen Controller für alle Routen innerhalb dieser Gruppe festlegen. Jetzt müssen wir die Methode angeben, die die Route aufrufen soll.

 Route::controller(UserController::class)->group(function () {
  Route::get('/orders/{userId}', 'getOrders');
  Route::post('/order/{id}', 'postOrder');
});

Subdomain-Routing

Ein Subdomain-Name ist eine zusätzliche Information, die an den Anfang des Domain-Namens einer Website angehängt wird. Damit können Websites ihre Inhalte für bestimmte Funktionen wie Online-Shops, Blogs, Präsentationen usw. vom Rest der Website trennen und organisieren.

Unsere Routen können für die Weiterleitung von Subdomains verwendet werden. Wir können die Domain und einen Teil der Subdomain zur Verwendung in unserem Controller und unserer Route abfangen. Mit Hilfe der Methode domain auf der Route Fassade können wir unsere Routen unter einer einzigen Domain zusammenfassen:

 Route::domain('{store}.enterprise.com')->group(function() {
  Route::get('order/{id}', function (Account $account, string $id) {
    // Your Code
  }
});

Präfixe und Namenspräfixe

Wenn wir eine Gruppe von Routen haben, können wir, anstatt sie einzeln zu ändern, die zusätzlichen Dienstprogramme nutzen, die Laravel bietet, wie prefix und name auf der Route Fassade.

Die Methode prefix kann verwendet werden, um jeder Route in der Gruppe einen bestimmten URI voranzustellen, und die Methode name kann verwendet werden, um jedem Routennamen einen bestimmten String voranzustellen.

So können wir neue Dinge wie Admin-Routen erstellen, ohne dass wir jeden einzelnen Namen oder jedes Präfix ändern müssen, um sie zu identifizieren:

 Route::name('admin.")->group(function() {
  Route::prefix("admin")->group(function() {
    Route::get('/get')->name('get');
    Route::put('/put')->name(put');
    Route::post('/post')->name('post');
  });
});

Die URIs für diese Routen lauten dann admin/get, admin/put, admin/post und die Namen admin.get, admin.put und admin.post.

Routen-Caching

Wenn die Anwendung auf Produktionsservern eingesetzt wird, nutzt ein guter Laravel-Entwickler den Routen-Cache von Laravel.

Was ist Route Caching?

Das Routen-Caching verkürzt die Zeit, die für die Registrierung aller Routen der Anwendung benötigt wird.

Beim Ausführen von php artisan route:cache wird eine Instanz von Illuminate/Routing/RouteCollection erzeugt und die serialisierte Ausgabe wird nach der Verschlüsselung in bootstrap/cache.routes.php geschrieben.

Nun wird jede andere Anfrage diese Cache-Datei laden, wenn sie existiert. Daher muss unsere Anwendung die Einträge aus der Routendatei nicht mehr parsen und in Illuminate/Routing/Route Objekte in Illuminate/Routing/RouteCollection umwandeln.

Warum es wichtig ist, Route Caching zu verwenden

Wenn du das Route Caching von Laravel nicht nutzt, riskierst du, dass deine Anwendung langsamer läuft, als sie könnte, was wiederum den Umsatz, die Benutzerbindung und das Vertrauen in deine Marke beeinträchtigen kann.

Je nach Umfang deines Projekts und je nachdem, wie viele Routen es gibt, kann ein einfacher Route-Caching-Befehl deine Anwendung um 130 % bis 500 % beschleunigen – ein enormer Gewinn für fast keinen Aufwand.

Zusammenfassung

Routing ist das Rückgrat der Backend-Entwicklung. Das Laravel-Framework zeichnet sich dadurch aus, dass es eine ausführliche Möglichkeit bietet, Routen zu definieren und zu verwalten.

Die Entwicklung kann in der Tat für jeden zugänglich sein und dazu beitragen, eine Anwendung zu beschleunigen, allein dadurch, dass sie in Laravel erstellt wurde.

Welche anderen Tricks und Tipps sind dir in Bezug auf Laravel-Routen begegnet? Lass es uns in den Kommentaren wissen!

Coman Cosmin

Cosmin Coman is a technology writer and developer with over 3 years of experience. Apart from writing for Kinsta, he has assisted in research at nuclear physics facilities and universities. Tech-savvy and integrated into the community, he always comes up with innovative solutions.