Middleware is computer software that separates two or more APIs and provides services such as rate-limiting, authentication, and logging. In Symfony you can achieve something like that using service decoration.
However, when decorating multiple services, the config is verbose and it's cumbersome to change the decoration order:
1 2 3 4 5 6 7 8 9
services:
App\Mailer\Mailer: ~
App\Mailer\RateLimitedMailer:
decorates: App\Mailer\Mailer
arguments: [20] # mails per second
App\Mailer\LoggingMailer:
decorates: App\Mailer\Mailer
That's why in Symfony 5.1 we've introduced a new syntax to chain several decorators using a new concept called "stack". This is the equivalent config of the previous example:
1 2 3 4 5 6 7
services:
App\Mailer\Mailer:
stack:
- App\Mailer\LoggingMailer: ~
- App\Mailer\RateLimitedMailer:
arguments: [20]
- App\Mailer\Mailer: ~
This new syntax (which is also available when using XML and PHP formats) makes it trivial to add/remove/reorder the decorating services. The main advantage of "stacks" over classic middleware is that middleware defines a domain-specific interface that each processing step must implement to be stackable. Stacks don't require this.
Additionally, stacks can be combined to create new stacks. Check the linked PR for more examples.
This is so awesome! Thank you <3
But
stack
represents no domain knowledge whatsoever.Stack is a general purpose term and in this case it's no better than say
list
Compare with:
decorators
. Now this is something that expresses our intentions explicitly and unambiguously.What's in
decorators
? Decorators!What's in a stack? Who knows, a collection of some values?!