Frontend Routing in einem Symfony2 Projekt

Avatar von Marco Jantke

Moderne Webapplikationen werden immer häufiger in der Form von Single Page Applications (SPA) umgesetzt. Die Verwaltung der Templates wird dabei im Frontend gehandhabt, das Backend dient als Daten-Schnittstelle. Ich möchte euch in diesem Artikel eine Nginx-Konfiguration für ein Symfony2 Projekt vorstellen, bei der die Auslieferung der Frontend-Resourcen über das öffentliche web-Verzeichnis der Symfony Applikation erfolgt und die Backendschnittstellen hinter einen /api-Prefix gelegt werden. Das Ziel soll dabei sein, dass die für den Endnutzer „sauberen“ URLs im Frontend gehandhabt werden. Also alle URLs die nicht mit /api beginnen, wie z.B. /gewinnspiel sollen im Frontend geroutet und dort das passende Template dafür geladen werden.

Getestet ist die Konfiguration mit Symfony 2.7.5 und einem nginx in der Version 1.6.2. Es sollte jedoch auch mit den meisten 2.x Versionen von Symfony und auch älteren Versionen von nginx funktionieren. Ein Beispiel-Syomfony2 Projekt könnt ihr in diesem Github Repository finden.

Nginx Konfiguration

Die Nginx ist bis auf wenige Stellen die empfohlene Nginx Konfiguration aus der Symfony2 Dokumentation.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
server {
server_name fe-routing-showcase.dev;
root /var/www/fe-routing-showcase/web;
location / {
# try to serve file without and with trailing / directly - everything else goes to app.php
try_files $uri $uri/ /index.html =404;
}
location ~ ^/api {
# rewrite everything behind /api to app.php
rewrite ^(.*)$ /app.php/$1 last;
}
# DEV
# This rule should only be placed on your development environment
# In production, don't include this and don't deploy app_dev.php or config.php
location ~ ^/(app_dev|config)\.php(/|$) {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# PROD
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
error_log /var/log/nginx/fe-routing-showcase_error.log;
access_log /var/log/nginx/fe-routing-showcase_access.log;
}
server { server_name fe-routing-showcase.dev; root /var/www/fe-routing-showcase/web; location / { # try to serve file without and with trailing / directly - everything else goes to app.php try_files $uri $uri/ /index.html =404; } location ~ ^/api { # rewrite everything behind /api to app.php rewrite ^(.*)$ /app.php/$1 last; } # DEV # This rule should only be placed on your development environment # In production, don't include this and don't deploy app_dev.php or config.php location ~ ^/(app_dev|config)\.php(/|$) { include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # PROD location ~ ^/app\.php(/|$) { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # Prevents URIs that include the front controller. This will 404: # http://domain.tld/app.php/some-path # Remove the internal directive to allow URIs like this internal; } error_log /var/log/nginx/fe-routing-showcase_error.log; access_log /var/log/nginx/fe-routing-showcase_access.log; }
server {
    server_name fe-routing-showcase.dev;
    root /var/www/fe-routing-showcase/web;

    location / {
        # try to serve file without and with trailing / directly - everything else goes to app.php
        try_files $uri $uri/ /index.html =404;
    }

    location ~ ^/api {
        # rewrite everything behind /api to app.php
        rewrite ^(.*)$ /app.php/$1 last;
    }

    # DEV
    # This rule should only be placed on your development environment
    # In production, don't include this and don't deploy app_dev.php or config.php
    location ~ ^/(app_dev|config)\.php(/|$) {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/app.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }

    error_log /var/log/nginx/fe-routing-showcase_error.log;
    access_log /var/log/nginx/fe-routing-showcase_access.log;
}

Symfony2 Anpassungen

In der Symfony Konfiguration habe ich lediglich auf der „höchsten“ Ebene einen /api-Prefix konfiguriert. Der Prefix kaskadiert dann durch alle konfigurierten Routen in der inkludierten Resource durch. Die komplette prefix-Konfiguration kann in folgendem Commit eingesehen werden. Beispiel:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
app:
resource: "@AppBundle/Controller/"
type: annotation
prefix: /api
app: resource: "@AppBundle/Controller/" type: annotation prefix: /api
app:
    resource: "@AppBundle/Controller/"
    type:     annotation
    prefix:   /api

Beispiele

Folgend nun einige Beispiele von URLs und wie sie geroutet werden:

  • / => index.html
  • /gewinnspiel => index.html
  • /api => /api/ => app.php, Request-Uri: /api/
  • /app_dev.php/api => /app_dev.php/api/ => Request-Uri: /api/ (development mode)

Mit dieser Konfiguration kann nun sämtliche Logik für das Routing und Templating in die SPA verschoben werden. Der Source-Code für die SPA kann dabei in einem Repository mit dem Symfony2 Projekt an einem zentralen Ort verwaltet werden. Ich hoffe das kann für einige von euren Projekten nützlich sein :)

Goodies von Mayflower

 

Das klingt nach einem Thema, dass Dich in Deinem Alltag bei euch beschäftigt? Das Dich mit vielen Fragen zurück lässt?

Keine Sorge – Hilfe ist nah! Melde Dich unverbindlich bei uns und wir schauen uns gemeinsam an, ob und wie wir Dich unterstützen können.

Unsere Data-Webinar-Reihe

Avatar von Marco Jantke

Kommentare

Schreibe einen Kommentar

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

Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.