Routing
Routing bezeichnet im Framework-Kontext den Vorgang, die für einen Request auf eine bestimmte URL-Adresse zuständige Controller-Methode zu ermitteln.
Hierfür ist die Bibliothek rhrz/router zuständig, deren Funktionalität in das Framework integriert ist. Die Bibliothek ist jedoch so programmiert, dass sie auch außerhalb des Frameworks genutzt werden kann.
Begriffsklärung
todo
Begriffe erläutern und abgrenzen:
- URL (Aufbau)
- Pfad
- Route
- Segmente
Deklaration
Routen werden als Attribute unmittelbar über den Controller-Methoden deklariert, auf die sie sich beziehen. Einer Controller-Methode können mehrere Routen zugeordnet sein.
namespace App\Controllers;
use RHRZ\Framework\Attributes\Route;
use RHRZ\Framework\Controller;
use RHRZ\Framework\Enums\HTTP;
class ProductController extends Controller
{
#[Route(HTTP::GET, 'products/:id/edit')]
public function edit($id)
{
// ...
}
}
Das Attribut Route
erhält folgende Parameter:
HTTP $method, string $route, string $name = null
$method
ist die HTTP-Methode, auf welche sich die Route beziehen soll. Zur Auswahl stehenGET
,POST
,PUT
undDELETE
, siehe REST-Routen.$route
ist die eigentliche Route, die auch Parameter enthalten kann.$name
ist der Name der Route, siehe Routen-Namen. Standardmäßig wird der Name automatisch generiert, kann jedoch über diesen Parameter überschrieben werden.
Parameter
Routen können variable Segmente enthalten, wodurch eine dynamische Zuordnung von URL-Pfaden zu Controller-Methoden ermöglicht wird. Die Werte dieser Segmente werden der Controller-Methode als Parameter übergeben. Es wird zwischen drei Arten von Routen-Parametern unterschieden. Eine Route ohne Parameter wird als statisch bezeichnet.
Notation | Typ | Beschreibung |
---|---|---|
foo/bar | static | Diese Route hat keine Parameter und trifft exakt auf die URL foo/bar zu. |
foo/:name | required | Diese Route erlaubt einen beliebigen Wert als zweites Segment der URL, zum Beispiel foo/bar oder foo/26 . |
foo/?name | optional | Diese Route verhält sich wie die vorherige, trifft aber auch auf foo alleine zu. Auf einen optionalen Parameter können ausschließlich weitere optionale Parameter oder ein Wildcard-Parameter folgen. |
foo/*name | wildcard | Diese Route trifft auf foo zu, gefolgt von einer beliebigen Anzahl an Segmenten, zum Beispiel foo/a/b/c , aber auch nur foo . Die Werte der Segmente werden als Array übergeben. Ein Wildcard-Parameter muss das letzte Segment einer Route sein. |
Die Priorität beim Routing entspricht der Reihenfolge der Tabelle. Statische Segmente haben also Vorrang vor jeder Art von Parameter. Erforderliche Parameter haben Vorrang vor optionalen Parametern, welche wiederum Vorrang vor Wildcard-Parametern haben. Es spielt somit keine Rolle, in welcher Reihenfolge die Routen in den Controllern deklariert werden, da Mehrdeutigkeit ausgeschlossen ist.
Folgende Route besitzt einen erforderlichen und zwei optionale Parameter. Sie trifft auf Pfade wie calendar/2020
, calendar/2020/12
und calendar/2020/12/31
zu.
#[Route(HTTP::GET, 'calendar/:year/?month/?day')]
WARNING
Es ist zu beachten, dass beim Routing keine Validierung vorgenommen wird. Diese Route würde also auch auf den Pfad calendar/foo/bar
zutreffen. Die Gültigkeit der Parameter muss in der Controller-Methode selbst überprüft werden.
Routen-Namen
Jeder Route wird ein eindeutiger Name zugeordnet, über den sie in Controllern und Views referenziert werden kann, zum Beispiel um Weiterleitungen oder Links zu erstellen. Der Vorteil ist, dass diese Referenzen auch dann gültig bleiben, falls sich die Deklaration der Route in der Zukunft ändert.
Standardmäßig wird der Routenname aus dem Klassennamen (ohne das Suffix Controller
) und dem Methodennamen gebildet, getrennt durch einen Punkt. Der Routenname zur Methode edit
der Klasse ProductController
lautet also product.edit
.
Bei Bedarf kann der automatisch generierte Name durch den letzten Parameter des Attributs Route
überschrieben werden. Das ist insbesondere dann notwendig, wenn einer Controller-Methode mehrere Routen zugeordnet werden sollen, die sonst den gleichen Namen erhalten würden.
Pfade generieren
Die Methode App::route(string $name, array|object $data = [])
generiert einen Pfad zu einer Route. Sie erhält als Parameter den Namen der Route sowie ein Array oder Objekt, dessen Werte in die Platzhalter der Route eingefügt werden. Falls ein numerisches Array übergeben wird, werden die Werte in der gegebenen Reihenfolge eingefügt. Wird ein assoziatives Array oder ein Objekt übergeben, so müssen die Indizes bzw. Eigenschaftsnamen den Namen der Routenparameter entsprechen.
App::route('product.edit', [5]); // products/5/edit
App::route('product.edit', ['id' => 5]); // products/5/edit
App::route('product.edit', [Product::find(5)]); // products/5/edit
Ein Link zu dieser Route kann in den Twig Views wie folgt erzeugt werden.
<a href="{{ app.route('product.edit', product) }}">Produkt bearbeiten</a>
REST-Routen
todo
Methode | Beschreibung |
---|---|
GET | Ressource(n) laden |
POST | neue Ressource erstellen |
PUT | komplette Ressource ersetzen oder erstellen |
PATCH | Ressource teilweise verändern |
DELETE | Ressource löschen |