fbpx

Symfony routing – znajdź swoją ścieżkę

Symfony routing – znajdź swoją ścieżkę

Niby prosty temat. Można by pomyśleć, że po co w ogóle o nim pisać. Symfony routing jak to routing – definiuje i jest. Nie do końca. Czasami nawet on potrafi przysporzyć problemów.

Konfiguracja globalna

Symfony ma już wbudowaną obsługę ścieżek więc nie musimy instalować dodatkowych bundli.  Odpowiada za nie Routing Component. Wystarczy, że odpowiednio skonfigurujemy routing w pliku config.yml.

framework:
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~

Ten zapis mówi, że wszystko, co dotyczy ścieżek, znajdziemy w pliku app/config/routing.yml. To właśnie w nim będziemy konfigurować ścieżki dla poszczególnych bundli. Strict_requirements określa, jak ma się zachować w momencie, gdy skonfigurowane parametry ścieżki są nieprawidłowe. Czy ma rzucić wyjątek (wartość: true) czy zwrócić null (wartość: false) albo mimo błędów spróbować dopasować ścieżkę (wartość: null). W zależności od środowiska strict powinien być odpowiednio ustawiony. Dla środowisk produkcyjnych zaleca się ustawianie go na wartość false lub null, zaś na developerskich na wartość true co ułatwi debugowanie.

Jak skonfigurować symfony routing dla bundla?

Gdy mamy już załatwioną konfigurację w pliku config.yml przejdźmy do pliku routing.yml znajdującego się w skonfigurowanej wyżej ścieżce. W moim przypadku zawiera on:

app:
 resource: "@AppBundle/Resources/config/routing.yml"
 prefix: /

opinion:
    resource: "@OpinionBundle/Resources/config/routing.yml"
    prefix:   /opinion

chart:
    resource: "@ChartBundle/Resources/config/routing.yml"
    prefix:   /chart

event:
    resource: "@EventBundle/Resources/config/routing.yml"
    prefix:   /event

user:
    resource: "@UserBundle/Resources/config/routing.yml"
    prefix:   /user

Zapis jest czytelny, łatwo się domyślić, że mamy tutaj skonfigurowane routingi dla poszczególnych bundli. Ten zapis oznacza, że routing na kolejnym poziomie, czyli już wewnątrz bundla będzie konfigurowany w pliku yml. Jeśli jednak chciałbyś trzymać konfigurację w postaci adnotacji, zapis wyglądałby tak:

app:
    resource: "@AppBundle/Controller/"
    type:     annotation

Konfiguracja akcji

W Symfony 3 mamy dwa sposoby na definiowanie routingu. Jak już wyżej wspomniałam, są to adnotacje i pliki konfiguracyjne yml.

Tak wygląda podstawowa definicja ścieżki w adnotacji, gdy nie potrzebujemy zawierać zmiennych w ścieżce:

/**
 * @Route("/add", name="event_add")
 */

W przypadku akcji edit, gdzie chcielibyśmy w gecie określić id eventu, który chcemy edytować, adnotacja wygląda następująco:

/**
 * @Route("/edit/{eventId}", name="event_edit")
 */

 Requirements

Zdefiniowaliśmy już ścieżkę ze zmienną, jednak w takiej postaci jak wyżej nie jest ona wystarczająco zabezpieczona. Aby określić takie rzeczy jak typ wartości zmiennej. Powinniśmy ustalić, że eventId jest liczbą. Zapis \d+ jest zwykłym wyrażeniem regularny oznaczającym liczby o nieokreślonej długości.

/**
 * @Route("/edit/{eventId}", name="event_edit", requirements={"eventId": "\d+"})
 */

Oczywiście możemy tworzyć też bardziej zaawansowane ścieżki i ich wymogi np. w przypadku aplikacji wielojęzycznych.

/**
     * @Route(
     *     "/event/{_locale}/{eventId}",
     *     requirements={
     *         "_locale": "en|fr",
     *         "eventId": "\d+"
     *     }
     * )
     */

W ścieżce możemy zdefiniować specjalne parametry tj.

  1. _controller – pozwala na zdefiniowanie, który kontroler ma być wywołany w danej ścieżce.
  2. _format – narzucenie formatu  np. /event.html.
  3. _fragment – stosowany w przypadku odniesienia do konkretnego elementu strony, gdy w ścieżce chcemy # np. /event#part.
  4.  _local – zastosowanie zaprezentowałam powyżej, używany do aplikacji wielojęzykowych.

Param Converter

Jedną z ciekawszych rzeczy, która usprawniła mi pracę z akcjami, jest Param Converter. W przypadku np. naszej akcji edit, gdy przekazujemy id, musimy w kontrolerze wywołać repozytorium, pobrać dane wydarzenie, obsłużyć błędy czy przypadki nieznalezienia. Jednak jest na to sposób. Możemy tę samą akcję zdefiniować tak:

/**
 * @Route("/event/{event}", name="event_edit")
 * @ParamConverter("event", class="EventBundle:Event")
 */
public function editAction(Event $event)
{
}

Dzięki Param Converterowi od razu dostajemy obiekt. W przypadku, gdy nie znajdzie obiektu, wyrzuci nam błąd, który możemy obsłużyć, przekierowując na inną stronę. Jest jedna bardzo ważna wada Param Convertera, jeśli chcemy go używać, musimy definiować ścieżki w formie adnotacji, nie ma wsparcia dla definicji w yml.

Param Converter jest  elementem bundla SensioFrameworkExtraBundle, który możemy zainstalować w ten sposób. W Symfony mamy już go wbudowanego.

composer require sensio/framework-extra-bundle

Zamierzałam opisać ten proces także w przypadku REST-a, ale po zastanowieniu stwierdziłam, że jest to na tyle rozbudowany temat, że zasługuje na osobny wpis. Zapraszam już niedługo. Jeśli masz pytania w temacie symfony routing albo problemy z konfiguracją, coś nie działa tak, jak chcesz, daj znać w komentarzu, razem coś wymyślimy.

Zgarnij darmowy ebook i cotygodniową dawkę wiedzy

.
Magdalena Limanówka-Kuciel
magdalena@panizkomputerem.pl

Jestem programistką, która lubi mieć ręce pełne roboty. Do życia potrzebuje komputera z internetem i kubka gorącej kawy. Więcej na stronie o mnie.