adagio/middleware
library allows to
implement middlewares with various data types easily., (*2)
Install Composer and run the following command to get the latest version:, (*3)
composer require adagio/middleware
todo., (*4)
Imagine you want to add a middleware pipeline to an existing image-editing library., (*5)
Here is the way you can do it without middlewares:, (*6)
// I want to solarize, rotate, unblur and then sepia my image (parameters are // voluntarily omitted for clarity). $image = (new SepiaFilter) ->filter((new UnblurFilter) ->filter((new RotateFilter) ->filter((new SolarizedFilter) ->filter(new Image('/path/to/image')))));
Problems are:, (*7)
With adagio/middleware
, you can do
it easily:, (*8)
use Adagio\Middleware\Stack; $pipe = new Stack([ new SolarizedFilter, new RotateFilter, new UnblurFilter, new SepiaFilter, ]); $image = $stack(new Image('/path/to/image'));
Filters have just to respect the following signature convention:, (*9)
function (Image $image, callable $next): Image { // Maybe do something with $image $resultingImage = $next($image); // Maybe do something with $resultingImage return $resultingImage; }
Each filter must pass the $image
to the $next
element of the pipe and can modify it before of after passing it., (*10)
Filters can be any callable respecting the given signature., (*11)
Middlewares are even more useful when the given and the returned objects are different. Think about a SQL query processor with the following signature:, (*12)
function (SqlQuery $query, ResultSet $resultSet, callable $next): ResultSet
You can then provide a caching middleware:, (*13)
final class QueryCache { // ... public function __invoke(SqlQuery $query, ResultSet $resultSet, callable $next): ResultSet { // If the query is already in cache, return the ResultSet and don't // trigger the rest of the middleware stack if ($this->resultSetCache->hasQuery($query)) { return $this->resultSetCache->getFromQuery($query); } $finalResultSet = $next($query, $resultSet); $this->resultSetCache->add($query, $finalResultSet); return $finalResultSet; } }
You can also provide a middleware that translates from a SQL standard to another, a SQL validator, a client-side cluster/shard solution, a logger, a performance monitor, ..., (*14)