Symfony 5: the fast track by Fabien Potencier A book review
I have recently worked my way through the new book by the creator of Symfony, Fabien Potencier, called Symfony 5: the fast track. With my background in Drupal 8 (based on Symfony 3.4 components) I recognised many things, and some are new to me because it's about Symfony, and some are new to me because it's Symfony 5.
NB: When talking about Drupal, I mean Drupal 8/9 (D9 = D8 - deprecations). When talking about Symfony, I mean Symfony 4.4/5 (S4.4 = S5 - deprecations) .
Choosing everything Symfony as seen from Drupal
The book is written in a clear and concise style, with enough humour to spice up the boring parts. It details the building of an application to track conference comments.
The author is founder of SensioLabs (the company behind Symfony) and Blackfire and uses (free to try) services from both companies a lot, especially in deployment and profiling. The symfony CLI tool is well integrated with SymfonyCloud, but if you prefer another hosting solution this won't help you.
The book touches on many many subjects concerning PHP development (in Symfony). To name a few:
- setting up a local dev environment, including using docker for local dev services
- CLI tools such as symfony, console and webpack
- essential Symfony components such as router, services, messenger, notifier, security, translations, events and caching
- extra Symfony components and bundles such as workflow, api, forms, automated tests, profiling, easy_admin
- building a CRUDS app, adding an API, making an SPA or native mobile app, deploying the app to servers, debugging and profiling the app
By touching on so many aspects of developing (in general and Symfony development in particular) the book feels very complete. You will get the most out of it if you are intermediate or advanced in PHP development skills. It is not called 'fast' track for no reason: in less than 300 pages all these aspects are touched upon. You will need to be curious and try things out for yourself, or skimp over subjects you are not that interested in. There a few inconsistencies and challenges (I had to install the apcu PHP extension, and found symfony CLI using the wrong version of PHP until I pinned it using a .php-version file) and I think beginners might need a fair bit of time to get everything working.
From a Drupal perspective bare-bones Symfony can be overwhelming: nothing is available out of the box and for everything multiple options exists. Case in point: session management. Where do you store your sessions? Drupal has a database table for this. Symfony can do this in a database, in memory, in redis, on the file system, etc. You have to decide.
Where Drupal makes a lot of (lower level) choices for your application, Symfony is very barebones and you will need to make a choice about many elements of your application. Symfony is very un-opinionated about these choices. This allows you to pick and choose only exactly what you need, with no superflous code.
If you need a reasonable amount of the features Drupal offers for your project, it might be the better (and easier) choice. Symfony will always be leaner, but you need to form an opinion about more technological implementation details.
Luckily Potencier is quite opinionated in his treatise of Symfony 5. He points out the choices you have and continues to choose one and implement that. This keeps the pace of the book nice and high. You can explore alternative choices at your leasure and come back when you're done. I did a few sidetrips on subjects that interested me for an upcoming project and found I could easily substitue the book's solution with another. Yay Symfony and its many components!
On the whole I thoroughly enjoyed Symfony 5: the fast track and I can recommend it to anyone who wants to get up to speed with all the great things Symfony has to offer. It's useful both for developers new to Symfony as developers familiar with older versions.
In more detail A Symfony 5 primer from a Drupal 8 perspective.
I will point out some of the things Symfony offers (or the book covers) that might be new or different for Drupal developers.
- using local php (for speed and simplicity, switchable using the symfony CLI tool) combined with docker for services (redis, mailcatcher, etc) that are harder to install locally/per project
- CLI tooling: symfony command
- sets PHP version and env variables. It can also connect to dockerized services. It should be the prefix before any CLI command (console, composer, php, phpunit)
- has a powerful dev php server build-in, including ssl support.
- CLI tooling: console command
- is the equivalent of drush (and Drupal console)
- has utilities for creating helpful scaffolds for entities, users, authentication, forms, translations
- can list debug info for routes, authentication, the container and autowiring, notifier, messenger, etc.
- can clear caches
- can run doctrine commands (equivalent of Drupal commands such as drush updb)
- you can easily create custom console commands, e.g. to use for cronjobs
- Storing variables and constants:
- passwords and tokens should be stored in Symfony secret storage or vaults
- dynamic values that can change without redeploying should be stored as environment variables
- if a value changes per environment (dev/test/prod) it should be stored as a container parameter
- otherwise best store the value in code, in a class constant.
- you can set service parameters and bind variables to services in the services.yaml config file.
- Webpack encore: symfony can integrate with webpack to provide a nice frontend toolchain including node, yarn, sass, etc.
- Symfony 5 development: you need a complete PHP installation including amqp.so which you might need to install. Symfony leverages many PHP 7 features directly.
- are autowired
- all classes in /src except Entity, Migrations and Tests are loaded as services.
- paths and prefixes can be i18n
- request format and method can be set or be required
- simple conditions and default values can be set inline
- Messenger and Notifier
- the messenger system is an async system akin to Drupal queues.
- define a Message, MessageHandler and a Transport. Consume the message with a Worker.
- the notifier system combines notifications in the browser (Symfony calls these flashes, akin to drupam_set_message) with email, sms, slack and other notification options. Notifications can have different priorities and use multiple notification channels at the same time.
- Security & Permissions
- the security system is called a firewall.
- defaults to none provided. No permissions, no (dynamic) roles, no users
- for simple apps an in-memory user provider can be enough
- for login with an external user source: no local user system is required.
- for login using an API: no GUI login (form) is required.
- password encoders: lots of choice, the standard UserPasswordEncoder does what you would mostly need and selects the best encryption available.
- Drupal has Roles and Permissions. Symfony has Roles (can be nested) and Permissions and Security voters.
- path based access for roles can be set in security.yaml (optionally including IP, host, port, method requirements)
- annotation based permissions can be given to roles on Controllers
- security Voters are used for fine grained access handling.
- Drupal masquerade functionality is included in the authentication system (quickly switching users)
- crude language switching can be done on URL prefix. Other methods you need to implement yourself or find a bundle.
- interface translation is handled by the symfony/translation composer package.
- uses ICU (International Components for Unicode) libraries for plurals
- translations are stored using the .xlf file format (XLIFF; XML Localisation Interchange File Format) and can be generated with a console command and shown on the Symfony Profiler Toolbar
- content translation is done using Doctrine extension bundles.
- a lot can be configured via class annotations: database tables and fields, validation, security and access, routing, parameters, api exposure, and more
- entity references can be set using annotions and the necessary database tables created using symfony console:make:entity
- Form types are available using HTML validation set by the database annotation.
- inline form errors are available
- file uploads are easily implemented
- the api-platform/api-pack symfony component allows you to expose entities using their annotation.
- includes a gui to browse the API including swagger files.
- requires very little configuration and setup to start of with.
- the workflow system introduces a state machine that can manage the state of an entity
- states are configured in a yaml file and the state process can be visualized using the dot CLI tool and symfony console workflow:dump
- works well together with the Messenger system
- Symfony uses event listeners to expand its core functionality (there are no Drupal hooks like system)
- You can list all events using symfony console debug:event-dispatcher
- Basic caching is done using the HTTP cache mechanism: using an external (reverse proxy) cache such as Varnish. This can cache until expired or use a validation strategy.
- You can set the HTTP cache headers and proxy cache headers in the Response objects
- Symfony supports ESI (Edge Side Includes) subrequests to achieve something similar to lazy loading page elements in Drupal Bigpipe.
- The symfony/cache component enables a local cache similar to the Drupal cache. There is no render cache: for this the native caching mechanisms of HTTP are used.
- Automated tests
- You can define fixtures and load them via a doctrine console command
- When writing automated tests there is a nice doctrine bundle that can reset the test database
- Symfony has a headless browser bundle that provides the 'panther' headless browser with drivers for Chrome and Firefox.
- You have access to the Symfony kernel during tests and can use this in your assertions.
- Blackfire player:
- The blackfire system is known for its profiler, but also contains a player that can be used for black-box testing.
About the author
Finne Fortuin is an expert PHP developer with a new found love of Symfony: a stack he's used since starting with Drupal 8 in 2016.