Symfony Bundles: Routenplanung mal anders

Bei einem so großen und vor allem so schnell wachsenden Framework wie Symfony, hinken einige Sachen immer etwas hinter dem Zeitplan her. So gibt es für das Schreiben eines Symfony Bundles viele gut Dokumentierte Vorgänge, jedoch fehlen auch für wichtige Aspekte die „Best-Practices“ oder gar ein gutes Beispiel. Aus gegebenem Anlass hier eine Hilfestellung zur Erstellung von Routen aus einem Bundle: „Symfony Bundles: Routenplanung mal anders“.

Ich möchte nicht, dass dieser Artikel nur als Kritik aufgefasst wird. Er soll vor allem die letzte Arbeitswoche an Recherche zu einem aktuellen Problem für mich zusammenfassen. Wenn dieser Artikel dabei auch anderen Entwicklern hilft, umso besser. Ich bin mir bewusst, dass Tests und Dokumentation genauso viel wiegen, wie die eigentliche Entwicklung an einem Projekt.

Informationen aus dem Web

Zum einen gibt es eine Dokumentation zu den Best Practices bei Erstellung eines Bundle. Das ist eine schöne Zusammenfassung für alle relevanten Aufgaben, die ein Bundle haben kann. Sucht man jedoch nach „Routes“ oder „Routing“, ist der einzige Hinweis ein relativ simpler:

If the bundle provides routes, they must be prefixed with the bundle alias. For example, if your bundle is called AcmeBlogBundle, all its routes must be prefixed with acme_blog_.

Okay, und wie genau definiere ich nun eine statische Route für meinen Controller im Bundle? Hierauf gibt der Artikel keine Antwort. Auch Referenzen auf weiterführende Artikel am Ende der Seite sucht man vergeblich. Im Hauptartikel für das Routing in Symfony finden wir dann aber zumindest weitere Informationen: In der Liste der weiterführenden Artikel befindet sich ein der Link zur Dokumentation für Custom Route Loader.

Die Konfiguration hier zeigt an, dass es neben dem Typ Annotation noch einen weiteren Typ directory gibt. Dieser lädt alle verwertbaren Konfigurationsdateien aus dem spezifizierten Ordner. Und hier finden wir endlich auch eine Referenz auf ein Bundle:

app_bundle:
    # loads routes from the YAML, XML or PHP files found in some bundle directory
    resource: '@AcmeOtherBundle/Resources/config/routing/'
    type: directory

Bis hier hin schön, aber was befindet sich in diesem Ordner? Und viel wichtiger: Wie genau sieht die Deklaration der Routen aus, damit Symfony sie auch versteht? Auf diese Fragen gibt der Artikel eine Antwort: Custom Services.

Routenplanung: Und weiter?

Nach dieser Beschreibung benötigen wir einen Service (entweder mit __invoke() oder einer beliebigen anderen Methode), der eine RouteColletion erstellt. Ein ziemlich einfaches Prinzip und sehr gut umzusetzen. Mit folgender Konfiguration werden unsere Routen dann in unserem Projekt geladen:

# config/routes.yaml
acme_routes:
    resource: '@AcmeOtherBundle/MyRoutesLoader::loadRoutes'
    type: service

Bedeutet für mich, dass hier schon mal eine wichtige Information fehlt: Man kann keine Routen aus einem Bundle heraus laden! Sie können in einem Bundle definiert werden. Konfiguriert man diese Ressourcen aber nicht im Projekt, sind sie auch nicht existent oder verwendbar. Ich muss also auch für meine Bundles daran denken, den Entwickler über meine Routen-Konfiguration zu informieren und wie er/sie diese zu laden vermag. Selbiges gilt auch für XML oder YAML Dateien, die ich in meinem Bundle verwalte.

Wie die Syntax für YAML und XML Dateien aussehen muss, kann auf der Seite der Routing Dokumentation nachgelesen werden. Es sei jedoch vermerkt, dass z.B. die XML Schemata nicht echt sind. Zumindest erhält man keine Antwort, wird der Link direkt aufgerufen.

Ein weiterer Ansatz für kompliziertere Routing Strategien ist der Chain-Router. Ein Komponente aus dem Symfony-CMF Bundle, die eigentlich aus dem Symfony 2 Universum kommt. Hiermit könnte man eventuell einen Router pro Projekt oder Bundle aufsetzen und dann alle Routen an einem Knoten zusammenführen. Da diese Möglichkeit für meine bisherigen Ansprüche viel zu hoch gestochen sind, habe ich mit hiermit nicht weiter auseinander gesetzt.

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.