In zend-expressive, you define a Zend\Expressive\Application instance and execute it. The Application instance is itself middleware that composes:

You can define the Application instance in two ways:

Regardless of how you setup the instance, there are several methods you will likely interact with at some point or another.



If you wish to manually instantiate the Application instance, it has the following constructor:

public function __construct(
    Zend\Expressive\MiddlewareFactory $factory,
    Zend\Stratigility\MiddlewarePipeInterface $pipeline,
    Zend\Expressive\Router\RouteCollector $routes,
    Zend\HttpHandlerRunner\RequestHandlerRunner $runner
) {

Container factory

We also provide a factory that can be consumed by a PSR-11 dependency injection container; see the container factories documentation for details.

Adding routable middleware

We discuss routing vs piping elsewhere; routing is the act of dynamically matching an incoming request against criteria, and it is one of the primary features of zend-expressive.

Regardless of which router implementation you use, you can use the following Application methods to provide routable middleware:


route() has the following signature:

public function route(
    string $path,
    array $methods = null,
    string $name = null
) : Zend\Expressive\Router\Route


This method is typically only used if you want a single middleware to handle multiple HTTP request methods.

get(), post(), put(), patch(), delete(), any()

Each of the methods get(), post(), put(), patch(), delete(), and any() proxies to route() and has the signature:

function (
    string $path,
    string $name = null
) : Zend\Expressive\Router\Route

Essentially, each calls route() and specifies an array consisting solely of the corresponding HTTP method for the $methods argument.


Because zend-expressive builds on zend-stratigility, and, more specifically, its MiddlewarePipe definition, you can also pipe (queue) middleware to the application. This is useful for adding middleware that should execute on each request, defining error handlers, and/or segregating applications by subpath.

The signature of pipe() is:

public function pipe($middlewareOrPath, $middleware = null)


Unlike Zend\Stratigility\MiddlewarePipe, Application::pipe() allows fetching middleware and request handlers by service name. This facility allows lazy-loading of middleware only when it is invoked. Internally, it wraps the call to fetch and dispatch the middleware inside a Zend\Expressive\Middleware\LazyLoadingMiddleware instance.

Read the section on piping vs routing for more information.

Registering routing and dispatch middleware

Routing and dispatch middleware must be piped to the application like any other middleware. You can do so using the following:


We recommend piping the following middleware between the two as well:


These allow your application to return:

See the section on piping to see how you can register non-routed middleware and create layered middleware applications.

Executing the application: run()

When the application is completely setup, you can execute it with the run() method. The method proxies to the underlying RequestHandlerRunner, which will create a PSR-7 server request instance, pass it to the composed middleware pipeline, and then emit the response returned.