Router
definiert, welche Middleware und Handler
eine HTTP-Anfrage verarbeiten. Dies ist die grundlegendste und zentrale Funktionalität in Salvo.
Intern besteht ein Router
aus einer Reihe von Filtern. Bei einer eingehenden Anfrage testet der Router der Reihe nach, ob er selbst oder seine Unterrouten die Anfrage matchen. Bei erfolgreichem Match werden die Middleware der gesamten Routenkette ausgeführt. Falls der Response
-Status auf einen Fehler (4XX, 5XX) oder eine Umleitung (3XX) gesetzt wird, werden nachfolgende Middleware und Handler
übersprungen. Sie können auch manuell ctrl.skip_rest()
aufrufen, um die weitere Verarbeitung zu überspringen.
Beim Matching gibt es einen URL-Pfad, der während des Prozesses vollständig von den Filtern verarbeitet werden muss. Nur wenn alle Filter erfolgreich sind und der gesamte Pfad verarbeitet wurde, gilt der Match als erfolgreich.
Beispiel:
Entspricht:
GET /articles/
würde erfolgreich matchen und list_articles
ausführen. GET /articles/123
würde jedoch fehlschlagen (404), da Router::with_path("articles")
nur /articles
verarbeitet, nicht den Rest /123
. Für solch einen Fall:
Hier matcht {**}
beliebige Restpfade, sodass GET /articles/123
erfolgreich list_articles
ausführt.
Routen können flach definiert werden:
Empfohlene baumartige Struktur:
Diese Struktur bleibt bei komplexen Projekten übersichtlich.
Viele Router
-Methoden geben Self
zurück für Methodenverkettung. Für bedingtes Routing gibt es then
:
Dies fügt nur im admin_mode
Routen zum Erstellen/Bearbeiten/Löschen von Artikeln hinzu.
{id}
definiert einen Parameter, der via Request
ausgelesen werden kann:
Für numerische IDs kann {id:num}
mit verschiedenen Formaten verwendet werden:
{id:num}
: Beliebige Ziffernfolge{id:num[10]}
: Genau 10 Ziffern{id:num(..10)}
: 1-9 Ziffern{id:num(3..10)}
: 3-9 Ziffern{id:num(..=10)}
: 1-10 Ziffern{id:num(3..=10)}
: 3-10 Ziffern{id:num(10..)}
: Mindestens 10 ZiffernPlatzhalter:
{**}
: Matcht optionalen Restpfad (auch leer){*+}
: Matcht nicht-leeren Restpfad{*?}
: Matcht optionales einzelnes PfadsegmentKombinationen sind möglich: /articles/article_{id:num}/
, /images/{name}.{ext}
.
Middleware wird via hoop
hinzugefügt:
Hier gilt check_authed
für alle Unterrouten. Für selektive Anwendung:
Router nutzen Filter für das Matching. Filter können mit or
/and
verknüpft werden. Ein Router matcht nur, wenn alle Filter erfolgreich sind.
Pfadfilter sind die häufigsten Filter:
Parameter werden via Request
ausgelesen:
Methodenfilter:
Entspricht:
Für häufig verwendete Muster können Kurzformen registriert werden. Beispiel für GUIDs:
Danach kann einfach {id:guid}
verwendet werden.
Routing-basierte Frameworks wie Salvo bieten gegenüber MVC/Controller-Ansätzen:
Routing bildet die API-Struktur direkt ab und eignet sich besonders für moderne Microservices und REST-APIs.
Kategorie | Methode | Beschreibung |
---|---|---|
Erstellung/Zugriff | new() | Neuen Router erstellen |
routers()/routers_mut() | Unterrouter abrufen | |
hoops()/hoops_mut() | Middleware abrufen | |
filters()/filters_mut() | Filter abrufen | |
Routenorganisation | unshift() | Router am Anfang einfügen |
insert() | An Position einfügen | |
push() | Router anhängen | |
append() | Mehrere Router anhängen | |
then() | Bedingte Konfiguration | |
Middleware | with_hoop()/hoop() | Middleware hinzufügen |
with_hoop_when()/hoop_when() | Bedingte Middleware | |
Pfadfilter | with_path()/path() | Pfadfilter hinzufügen |
with_filter()/filter() | Filter hinzufügen | |
with_filter_fn()/filter_fn() | Funktionsfilter | |
Netzwerkfilter | scheme() | Protokollfilter |
host()/with_host() | Hostfilter | |
port()/with_port() | Portfilter | |
HTTP-Methoden | get()/post()/put() | HTTP-Methodenrouten |
delete()/patch()/head()/options() | HTTP-Methodenrouten | |
Handler | goal() | Handler setzen |
Matching | detect() | Routenmatch prüfen |