El enrutamiento es un mecanismo que reescribe las URL para simplificar su aspecto. Antes de poder comprender su importancia, es necesario dedicar unos minutos al estudio de las URL de las aplicaciones
Cuando el usuario realiza una acción, las URL se encargan de enviar la información desde el navegador hasta el servidor. Las URL tradicionales incluyen la ruta hasta el script del servidor y algunos parámetros necesarios para completar la petición, como se muestra en el siguiente ejemplo:
http://www.ejemplo.com/web/controlador/articulo.php?id=123456&codigo_formato=6532
La URL anterior incluye información sobre la arquitectura de la aplicación y sobre su base de datos. Normalmente, los programadores evitan mostrar la estructura interna de la aplicación en la interfaz (las páginas por ejemplo se titulan "Perfil personal" y no "QZ7.65"). Desvelar detalles internos de la aplicación en la URL no solo contradice esta norma, sino que tiene otras desventajas:
id? ¿Supone este caso que la aplicación ofrece una interfaz directa a la base de datos? ¿Qué sucedería si otro usuario probara otros nombres de script, como por ejemplo admin.php? En resumen, las URL directas permiten jugar de forma directa y sencilla con una aplicación y es casi imposible manejar su seguridad.
Figura 9.1. Las URL aparecen en muchos lugares, como por ejemplo los resultados de búsqueda
La situación podría ser incluso mucho peor si Symfony no utilizara un controlador frontal; es decir, si la aplicación contiene varios scripts accesibles desde el exterior, como por ejemplo:
http://www.ejemplo.com/web/galeria/album.php?nombre=mis%20vacaciones http://www.ejemplo.com/web/weblog/publico/post/listado.php http://www.ejemplo.com/web/general/contenido/pagina.php?nombre=sobre%20nosotros
En este caso, los programadores deben hacer coincidir la estructura de las URL y la estructura del sistema de archivos, por lo que su mantenimiento se convierte en una pesadilla cuando cualquiera de las dos estructuras se modifica.
Una de las ideas del sistema de enrutamiento es utilizar las URL como parte de la interfaz. Las aplicaciones trasladan información al usuario mediante el formateo de las URL y el usuario puede utilizar las URL para acceder a los recursos de la aplicación.
Lo anterior es posible en las aplicaciones Symfony porque la URL que se muestra al usuario no tiene que guardar obligatoriamente relación con la instrucción del servidor necesaria para completar la petición. En su lugar, la URL está relacionada con el recurso solicitado, y su aspecto puede configurarse libremente. En Symfony es posible por ejemplo utilizar la siguiente URL y obtener los mismos resultados que la primera URL mostrada en este capítulo:
http://www.ejemplo.com/articulos/economia/2006/sectores-actividad.html
Este tipo de URL tiene muchas ventajas:
Figura 9.2. Las URL pueden incluir información adicional sobre una página, como por ejemplo su fecha de publicación
http://www.ejemplo.com/controlador/web/index.jsp?id=ERD4, probablemente no reciba muchas visitas.// Listado de resultados: se puede añadir una nueva etiqueta para restringir los resultados http://del.icio.us/tag/symfony+ajax // Página de perfil de usuario: se puede modificar el nombre para obtener otro perfil http://www.askeet.com/user/francois
.php, .asp, etc.) Así que si se formatean las URL de esta forma, los buscadores creen que están indexando contenidos estáticos, por lo que generalmente se obtiene una mejor indexación de las páginas de la aplicación.La relación entre las URL mostradas al usuario y el nombre del script que se ejecuta y de sus parámetros está gestionada por el sistema de enrutamiento, que utiliza patrones que se pueden modificar mediante la configuración de la aplicación.
¿Qué sucede con los contenidos estáticos? Afortunadamente, las URL de los contenidos estáticos (imágenes, hojas de estilos y archivos de JavaScript) no suelen mostrarse durante la navegación, por lo que no es necesario utilizar el sistema de enrutamiento para este tipo de contenidos. Symfony almacena todos los contenidos estáticos en el directorio web/ y sus URL se corresponden con su localización en el sistema de archivos. No obstante, es posible gestionar dinámicamente los contenidos estáticos mediante URL generadas con un helper para contenidos estáticos. Por ejemplo, para mostrar una imagen generada dinámicamnete, se puede utilizar el helper image_tag(url_for('captcha/image?key='.$key)).
Symfony desasocia las URL externas y las URI utilizadas internamente. La correspondencia entre las dos es responsabilidad del sistema de enrutamiento. Symfony simplifica este mecanismo utilizando una sintaxis para las URI internas muy similar a la de las URL habituales. El listado 9-1 muestra un ejemplo.
Listado 9-1 - URL externas y URI internas
// Sintaxis de las URI internas <modulo>/<accion>[?parametro1=valor1][¶metro2=valor2][¶metro3=valor3]... // Ejemplo de URI interna que nunca se muestra al usuario articulo/permalink?ano=2006&tema=economia&titulo=sectores-actividad // Ejemplo de URL externa que se muestra al usuario http://www.ejemplo.com/articulos/economia/2006/sectores-actividad.html
El sistema de enrutamiento utiliza un archivo de configuración especial, llamado routing.yml, en el que se pueden definir las reglas de enrutamiento. Si se considera la regla mostrada en el listado 9-2, se define un patrón cuyo aspecto es articulos/*/*/* y que también define el nombre de cada pieza que forma parte de la URL.
Listado 9-2 - Ejemplo de regla de enrutamiento
articulo_segun_titulo: url: articulos/:tema/:ano/:titulo.html param: { module: articulo, action: permalink }
Todas las peticiones realizadas a una aplicación Symfony son analizadas en primer lugar por el sistema de enrutamiento (que es muy sencillo porque todas las peticiones se gestionan mediante un único controlador frontal). El sistema de enrutamiento busca coincidencias entre la URL de la petición y los patrones definidos en las reglas de enrutamiento. Si se produce una coincidencia, las partes del patrón que tienen nombre se transforman en parámetros de la petición y se juntan a los parámetros definidos en la clave param:. El listado 9-3 muestra su funcionamiento.
Listado 9-3 - El sistema de enrutamiento interpreta las URL de las peticiones entrantes
// El usuario escribe (o pulsa) sobre esta URL externa http://www.ejemplo.com/articulos/economia/2006/sectores-actividad.html // El controlador frontal comprueba que coincide con la regla articulo_segun_titulo // El sistema de enrutamiento crea los siguientes parámetros de la petición 'module' => 'articulo' 'action' => 'permalink' 'tema' => 'economia' 'ano' => '2006' 'titulo' => 'sectores-actividad'
La extensión .html de las URL externas es solo un adorno y por ese motivo el sistema de enrutamiento la ignora. Su única función es la de hacer que las páginas dinámicas parezcan páginas estáticas. La sección "Configuración del enrutamiento" al final de este capítulo explica cómo activar esta extensión.
Después, la petición se pasa a la acción permalink del módulo articulo, que dispone de toda la información necesaria en los parámetros de la petición para obtener el artículo solicitado.
El mecanismo de enrutamiento también funciona en la otra dirección. Para mostrar las URL en los enlaces de una aplicación, se debe proporcionar al sistema de enrutamiento la información necesaria para determinar la regla que se debe aplicar a cada enlace. Además, no se deben escribir los enlaces directamente con etiquetas <a> (ya que de esta forma no se estaría utilizando el sistema de enrutamiento) sino con un helper especial, tal y como se muestra en el listado 9-4.
Listado 9-4 - El sistema de enrutamiento formatea las URL externas mostradas en las plantillas
// El helper url_for() transforma una URI interna en una URL externa <a href="<?php echo url_for('articulo/permalink?tema=economia&ano=2006&titulo=sectores-actividad') ?>">pincha aquí</a> // El helper reconoce que la URI cumple con la regla articulo_segun_titulo // El sistema de enrutamiento crea una URL externa a partir de el => <a href="http://www.ejemplo.com/articulos/economia/2006/sectores-actividad.html">pincha aquí</a> // El helper link_to() muestra directamente un enlace // y evita tener que mezclar PHP y HTML <?php echo link_to( 'pincha aqui', 'articulo/permalink?tema=economia&ano=2006&titulo=sectores-actividad' ) ?> // Internamente link_to() llama a url_for(), por lo que el resultado es el mismo => <a href="http://www.ejemplo.com/articulos/economia/2006/sectores-actividad.html">pincha aquí</a>
De forma que el enrutamiento es un mecanismo bidireccional y solo funciona cuando se utiliza el helper link_to() para mostrar todos los enlaces.
Capítulo original en inglés Chapter 9 - Links And The Routing System Traducido por Javier Eguíluz