From ddee30f38ed214b30b19cd68f5ec4ffc52050a29 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 19 Mar 2018 15:36:33 -0500 Subject: [PATCH] Documents how to segregate middleware by host This patch demonstrates how to segregate middleware by host, using the `Zend\Stratigility\host()` function, along with the `MiddlewareFactory`. In trying to determine where to put this in the cookbook, I ended up re-ordering the cookbook to provide a bit of a "progression" of topics. --- .../v3/cookbook/host-segregated-middleware.md | 72 +++++++++++++++++++ mkdocs.yml | 9 +-- 2 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 docs/book/v3/cookbook/host-segregated-middleware.md diff --git a/docs/book/v3/cookbook/host-segregated-middleware.md b/docs/book/v3/cookbook/host-segregated-middleware.md new file mode 100644 index 00000000..4eb98bc6 --- /dev/null +++ b/docs/book/v3/cookbook/host-segregated-middleware.md @@ -0,0 +1,72 @@ +# How does one segregate middleware by host? + +If your application is being re-used to respond to multiple host domains, how +can you segregate middleware to work only in reponse to a specific host request? + +As an example, perhaps you have an "admin" area of your application you only +want to expose via the host name "admin.example.org"; how can you do this? + +## The host function + +[Stratigility](https://docs.zendframework.com/zend-stratigility/) provides a +function, `Zend\Stratigility\host()` that can be used to decorate middleware in +a `Zend\Stratigility\Middleware\HostMiddlewareDecorator` instance. These expect +the string name of a host, and the middleware that should only trigger when that +host is matched in the request. + +As a simple example: + +```php +// in config/pipeline.php: +use function Zend\Stratigility\host; + +$app->pipe(host('admin.example.org', $adminMiddleware)); +``` + +However, you'll note that the above uses an already instantiated middleware +instance; how can you lazy-load a named service instead? + +## Lazy-loading host-segregated middleware + +The `config/pipeline.php` file defines and returns a callable that accepts three +arguments: + +- a `Zend\Expressive\Application $app` instance +- a `Zend\Expressive\MiddlewareFactory $factory` instance +- a `Psr\Container\ContainerInterface $container` instance + +We can use the second of these to help us. We will use the `lazy()` method to +specify a middleware service name to lazy-load: + +```php +$app->pipe(host('admin.example.org', $factory->lazy(AdminMiddleware::class))); +``` + +What about specifying a pipeline of middleware? For that, we can use the +`pipeline()` method of the factory: + +```php +$app->pipe(host('admin.example.org', $factory->pipeline( + SessionMiddleware::class, + AuthenticationMiddleware::class, + AuthorizationMiddleware::class, + AdminHandler::class +))); +``` + +Alternately, either of the above examples could use the `prepare()` method: + +```php +// lazy example: +$app->pipe(host('admin.example.org', $factory->prepare(AdminMiddleware::class))); + +// pipeline example: +$app->pipe(host('admin.example.org', $factory->prepare([ + SessionMiddleware::class, + AuthenticationMiddleware::class, + AuthorizationMiddleware::class, + AdminHandler::class, +]))); +``` + +> For more information on the `MiddlewareFactory`, [read its documentation](../features/container/middleware-factory.md). diff --git a/mkdocs.yml b/mkdocs.yml index 641274b7..2c00ced1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -48,17 +48,18 @@ pages: - Emitters: v3/features/emitters.md - Cookbook: - 'Autowiring routes and pipeline middleware': v3/cookbook/autowiring-routes-and-pipelines.md + - 'Using Expressive from a subdirectory': v3/cookbook/using-a-base-path.md - 'Prepending a common path to all routes': v3/cookbook/common-prefix-for-routes.md + - 'Passing data between middleware': v3/cookbook/passing-data-between-middleware.md - 'Route-specific middleware pipelines': v3/cookbook/route-specific-pipeline.md - - 'Registering custom view helpers when using zend-view': v3/cookbook/using-custom-view-helpers.md + - 'Segregating middleware by host': v3/cookbook/host-segregated-middleware.md - 'Using double-pass middleware': v3/cookbook/double-pass-middleware.md - - 'Using zend-form view helpers': v3/cookbook/using-zend-form-view-helpers.md - - 'Using Expressive from a subdirectory': v3/cookbook/using-a-base-path.md - 'Setting a locale based on a routing parameter': v3/cookbook/setting-locale-depending-routing-parameter.md - 'Setting a locale without a routing parameter': v3/cookbook/setting-locale-without-routing-parameter.md - 'Enabling debug toolbars': v3/cookbook/debug-toolbars.md - 'Flash Messengers': v3/cookbook/flash-messengers.md - - 'Passing data between middleware': v3/cookbook/passing-data-between-middleware.md + - 'Registering custom view helpers when using zend-view': v3/cookbook/using-custom-view-helpers.md + - 'Using zend-form view helpers': v3/cookbook/using-zend-form-view-helpers.md - Reference: - "Why choose Expressive?": v3/why-expressive.md - "CLI Tooling": v3/reference/cli-tooling.md