Symfony 4: Buenas prácticas
Symfony 4 se publicará en Noviembre de 2017. Esta serie de artículos explica sus principales novedades:
- Symfony 4 (parte 1): Componer en vez de heredar
- Symfony 4 (parte 2): Microaplicaciones y monolitos
- Symfony 4 (parte 3): Buenas Prácticas
- Symfony 4 (parte 4): Estructura de directorios
- Symfony 4 (parte 5): Automatización
- Symfony 4 (parte 6): Un ejemplo práctico
- Symfony 4 (parte 7) (se publicará próximamente)
- Symfony 4 (parte 8) (se publicará próximamente)
Cuando se publica una nueva versión major de un proyecto (como por ejemplo Symfony 2.0, 3.0, 4.0, etc.) es el momento perfecto para repensar sus buenas prácticas y modernizarlas si hace falta. Symfony 4 no será una excepción y por eso vamos a adaptar algunas de las buenas prácticas actuales a las nuevas funcionalidades que introduce Symfony 4.
Estandarizar todo lo que se pueda
El primer paso de la evolución de las buenas prácticas de Symfony será la utilización de tantas herramientas estándar como sea posible.
Symfony no para de adoptar estándares tanto web como PHP, así que cuesta creer que cuando comenzamos a desarrollar Symfony 2, Composer todavía no existía. Desde entonces, han surgido iniciativas como el "FIG Group", que desarrolla estándares dentro del ámbito PHP, llamados PSR (PHP Standards Recommendations).
Symfony fue uno de los primeros frameworks importantes en adoptar la mayoría de PSR y lo hizo sin romper la compatibilidad con las aplicaciones existentes: PSR-3 para los logs, PSR-4 para la carga automática de clases y PSR-6 para la cache. En Symfony 3.3 hemos añadido soporte para PSR-16 (caché simplificada) y PSR-11 (contenedores de servicios).
El uso de estándares aumenta la interoperabilidad entre aplicaciones y permite desacoplar el código de tus proyectos respecto al framework Symfony.
Aplicaciones sin bundles
En el artículo anterior explicamos la decisión de hacer que las aplicaciones Symfony dejen de usar bundles. Lo mencionamos de nuevo aquí simplemente como recordatorio porque es uno de los cambios más importantes de las nuevas buenas prácticas de Symfony.
Variables de entorno
En el libro Las Buenas Prácticas Oficiales de Symfony
se explica con detalle cómo gestionar la configuración de las aplicaciones
Symfony. Por ejemplo, cómo usar app/config/parameters.yml
para las opciones de
configuración relacionadas con la infraestructura (por ejemplo, tu base de
datos) y cómo usar app/config/config.yml
para las opciones de configuración
relacionadas con la aplicación.
Nuestra primera recomendación es que no utilices opciones de configuración de
las que se guardan en app/config/config.yml
a menos que sea imprescindible. De
hecho, en nuestra opinión, se pueden contar con los dedos de una mano los casos
en los que es necesario definir una opción de ese tipo.
Por otra parte, en Symfony 4 también desaparece el archivo app/config/parameters.yml
.
En su lugar se utilizan variables de entorno, tal y como hacen la mayoría de
frameworks en otros lenguajes de programación. Además, esta es una de las recomendaciones
recogidas en el 12-Factor Application Manifesto
que siguen la mayoría de plataformas de hosting modernas.
Aunque las variables de entorno no son perfectas, tienen varias ventajas
respecto a usar el archivo parameters.yml
. Para empezar, las variables de
entorno son el mecanismo estandar en la industria para gestionar la
configuración que depende del entorno de ejecución (son mucho más cómodas por
ejemplo que tener que lidiar con el archivo parameters.yml.dist
).
Además, las variables de entorno se pueden leer desde distintas herramientas, ya que son independientes del código, del framework y del lenguaje de programación. Las variables de entorno también son útiles en los sistemas de archivos de solo lectura, ya que están desacopladas de tu código y su valor se puede cambiar dinámicamente sin tener que desplegar de nuevo la aplicación (y sin tener que borrar la caché de la aplicación Symfony).
Su única pega es que, a diferencia de lo que algunos programadores creen, las variables de entorno son igual de inseguras que los archivos de configuración a la hora de guardar valores secretos como contraseñas y tokens de APIs.
Utilizar variables de entorno mientras se desarrolla la aplicación es un poco
pesado, así que vamos a recomendar el uso de un archivo estándar llamado .env
.
Symfony 3.3 incluye un nuevo componente llamado Dotenv
que se utilizará por defecto en las aplicaciones Symfony 4. Así que el cambio
entre un archivo .env
y las variables de entorno "de verdad" será automática y
transparente para ti.
Si lo prefieres, puedes seguir definiendo las variables de entorno en un archivo
llamado parameters.yaml
, aunque esta ya no será la forma estándar de trabajar.
Por cierto, el nombre parameters.yaml
no es un error al escribir parameters.yml
.
De hecho, este será otro cambio de Symfony 4 que discutiremos más adelante.
Una ventaja añadida de usar variables de entorno es que simplifica la forma en
la que se gestiona el entorno de ejecución (dev
, prod
, etc.) y el valor de
la opción debug
tanto en la consola como en los controladores frontales.
Actualmente, se pueden definir el entorno y el debug que utiliza ./bin/console
tanto con las opciones --env
y --no-debug
como con las variables de entorno
SYMFONY_ENV
y SYMFONY_DEBUG
. En Symfony 4 esto ya no es necesario, ya que
se utilizarán las variables de entorno APP_ENV
y APP_DEBUG
tanto en la consola
como en los controladores frontales.
Así que ta te puedes ir olvidando de ./bin/console foo:bar --env=prod --no-debug
o SYMFONY_ENV=prod SYMFONY_DEBUG=0 ./bin/console foo:bar
. Simplemente utiliza
./bin/console foo:bar
y todo funcionará como esperas. Tanto en desarrollo como
en producción. Por cierto, Symfony 4 está lleno de simplificaciones de este tipo.
Un solo controlador frontal
Symfony 3 tiene dos controladores frontales. Uno está optimizado para producción
(app.php
) y el otro para desarrollo (app_dev.php
). Symfony 4 solo tiene un
controlador frontal, así que ya no tienes que borrar el controlador frontal de
desarrollo cuando despliegues la aplicación. Y ya no sufrirás ningún problema de
seguridad si te olvidas de hacerlo.
A lo mejor estás pensando que esto hará que el código sea más complejo que antes. No es el caso, porque hemos podido borrar un montón de código antiguo. Y todo gracias a las variables de entorno, gracias a PHP 7 (que hace innecesarios los archivos de bootstrap y la caché de clases) y gracias a Symfony 3.3 (que elimina la necesidad de usar un cargador automático de clases).
El archivo Makefile
En muchos proyectos es habitual tener scripts propios para ejecutar tareas: ejecutar los tests unitarios o de integración, arrancar el servidor web interno de PHP, etc. En estos casos no tiene mucho sentido crear un comando de Symfony para ejecutar este tipo de scripts.
También es habitual, por comodidad, definir algunos de esos scripts en el
archivo composer.json
de la aplicación. Silex por ejemplo hace eso con el
script que arranca el servidor web interno de PHP. Lo malo es que es difícil
gestionar cosas como los timeouts o la falta de soporte de las secuencias de
escape ANSI de los comandos.
En cualquier caso, sea en el archivo composer.json
o en otro lugar, tener
todos estos scripts centralizados en un sitio es muy útil. ¿Y si usamos para
ello un archivo Makefile
? Este es posiblemente el cambio más controvertido de
Symfony 4. Hemos estado dudando muchísimo sobre si hacer este cambio o no. Al
final hemos decidido hacerlo porque aporta un gran valor y resuelve algunos de
nuestros problemas.
Puede que ya conozcas la herramienta make
, porque es bastante conocida y
"estándar" en el ámbito de la programación. Se trata de una herramienta mucho
más poderosa que los scripts que ejecuta Composer. Además no requiere del uso de
PHP. Se puede utilizar para desplegar aplicaciones, conectarte mediante SSH a
servidores remotos, ejecutar npm, gulp, webpack, Blackfire, etc. En definitiva,
muchos casos de uso en los que los comandos tradicionales de Symfony no son
prácticos.
Make además es muy poderoso, ya que puede ejecutar tareas en paralelo, evitar la ejecución de tareas si no ha habido cambios, etc.
Vamos a ver un ejemplo: el borrado de la caché. Symfony tiene un comando para
borrar la caché y otro para pre-generar la caché. Sin embargo, hacer las dos
cosas en el mismo proceso no funciona bien porque PHP no es capaz de recargar
una clase cuando su contenido cambia. Pero hacerlo con make
es facilísmo:
cache-clear: @test -f bin/console && bin/console cache:clear --no-warmup || rm -rf var/cache/* .PHONY: cache-clear cache-warmup: cache-clear @test -f bin/console && bin/console cache:warmup || echo "cannot warmup the cache (needs symfony/console)" .PHONY: cache-warmup
Otro ejemplo práctico: la mayoría de mis proyectos PHP tienen estas dos tareas para ejecutar los tests de Blackfire automáticamente:
bf-dev: blackfire-player --endpoint=http://`bin/console server:status --filter=address` run tests/bkf/all.bkf .PHONY: bf-dev bf-prod: blackfire-player --endpoint=https://twig.sensiolabs.org run tests/bkf/all.bkf --variable="env=prod" .PHONY: bf-prod
Otro caso de uso de make
es poner una aplicación en modo "mantenimiento"
mientras haces cambios. Mucho más cómodo que hacerlo con un comando de Symfony.
Gestionando los assets
La versión 3.0 de la edición estándar de Symfony eliminó Assetic. Por el momento no recomendamos ninguna herramienta para sustituir a Assetic, ya que el mundo JavaScript está todavía inmerso en la búsqueda de una herramienta estándar para gestionar los assets de las aplicaciones web.
No obstante, Symfony 4 recomendará el uso de una herramienta y proporcionará
integración con ella. Los detalles los anunciaremos dentro de unas semanas.
Por el momento, queríamos mencionar que Symfony 4 seguirá existiendo el comando
assets:install
para copiar o enlazar simbólicamente los assets de los bundles
dentro del directorio public/bundles/
. En Symfony 5 seguramente cambiaremos todo
esto, ya que no tiene mucho sentido ahora que las aplicaciones ya no tienen bundles.
La implementación de todas estas buenas prácticas supondrá algunos cambios en la estructura de directorios de las aplicaciones Symfony. Y ese será precisamente el tema del próximo artículo. No te lo pierdas.
Este artículo es una traducción del artículo Symfony 4: Best Practices publicado por Fabien Potencier.
Comentarios
Proyectos Symfony destacados
La forma más sencilla de generar el backend de tus aplicaciones Symfony. Ver más
Síguenos en @symfony_es para acceder a las últimas noticias.