Talk: https://joind.in/talk/18336
This is a fork of "Symfony Demo Application":
- In
xkey
branch it adds code to show FosHttpCache and Varnish xkey usage, and Docker images to demonstrate it. - In
fastly
branch it adapts that to show an example (simple poc) of how a Fastly Proxy Client for FosHttpCache can be made.
For full docker setup usage:
- Docker + Docker Compose in some 2018 flavour or higher
- For combining use of local PHP + Docker, use either PHP 7.1 or 7.2 (7.2 is default, see
docker-composer.yml
to change to 7.1)
For plain PHP web server usage (no caching, but able to see raw headers and browse around the demo):
- PHP 7.1.3 or higher;
- PDO-SQLite PHP extension enabled;
- and the [usual Symfony application requirements][1].
$ git clone https://github.com/andrerom/sf-london-2018-httpcache-demo.git
$ cd sf-london-2018-httpcache-demo
$ composer install
At this point, or later if you want, adapt generated .env to enable APP_ENV=prod and APP_DEBUG=0 In prod you'll be able to see things being cached, while in dev you'll be able to see all headers.
$ docker-compose up --abort-on-container-exit --force-recreate
# To debug calls to Varnish in separate console (see bottom of docker-compose.yml for more info):
$ docker-compose exec varnish varnishlog -g request -q "ReqMethod eq 'PURGEKEYS'"
On Docker for Mac you'll for instance end up with:
- http://localhost:8081 (Varnish, to see headers and Varnish in action)
- http://localhost:8080 (Nginx, to see headers from backend)
Check documentation for your docker installation if in doubt.
TODO: Enable AppCache in this repo (only when not using Varnish...), to showcase most feature of FosHttpCache still working.
$ php bin/console server:run
TIP You can also see this online in comparison view: https://github.com/symfony/demo/compare/master...andrerom:xkey
A Docker setup with Varnish (with xkey VMOD), Nginx, PHP & MariaDB stack, see:
docker-compose.yml
docker/*
Adds FosHttpCache by means of:
composer require friendsofsymfony/http-cache-bundle guzzlehttp/psr7 php-http/guzzle6-adapter
- Configure it in
config/packages/fos.yml
Adjusts frontend src/Controller/BlogController.php
to showcase caching + tagging for:
index()
action (en/blog/)postShow()
action (en/blog/posts/*)
For cache invalidation backend src/Controller/Admin/BlogController.php
is modified on:
new()
clearposts
tag (frontend index view)edit()
anddelete()
is modified to invalidatepost-<id>
andpost
tags for the two affected frontend views.
Fixes bug in Symfony Demo using flash messages triggering session start:
- See
templates/default/_flash_messages.html.twig
- TIP: See link inline there on how to change flash messages to be cache safe (not end up storing flash messages in cache..).
- Ref: https://symfony.com/doc/current/session/avoid_session_start.html
Enabling User Context Hash feature to explore caching pages for users with sessions and logged in users:
config/packages/fos.yml
(user_context
section)config/packages/security.yaml
config/routes/fos.yml
docker/varnish/default.vcl
(addsfos_user_context*.vcl
imports)src/Controller/BlogController.php
(addsvary={"X-User-Context-Hash"}
on Cache annotation)- NOTE: This is broken ATM in the code, so you'll need to remember to delete cookie to receive cached pages right now.
Easy pick?
- This issue you should be able to figure out with the info found in code + slides here, but since comments are
rendered inline in Blog post
post_show.html.twig
template,commentNew()
action needs to be adapted to invalidate tag for post entities.
Medium to hard? _If cache where fully enabled also when having session/logged-in within the demo, we will run into 2 issues:
-
New Comment form when you are logged in: This contains a CSRF token, this can not be cached. It will end up with error for other users, and is a security issue as it will expose someone else's token.
-
Let's say we want to add Flash message to
commentNew()
, how can you do that in a cache safe way?
Hard? (Effort: Rather large, so take this as a taught experiment to suggest upstream how it could be done) 4. By now the talk + code + the answers you have found above have just made it within reach to see how even the admin backend even can be cached with some careful handling.
How would you approach these? Feel free to open issue to discuss, or even a PR so others can have a look. And who knows, maybe all of this at a later point ends up in Symfony Demo in some form to serve as best practice ;)