On this page
Routing Adapters
Routing Interface
Mezzio defines Mezzio\Router\RouterInterface
, which is used by
the Mezzio\Router\RouteMiddleware
— as well as the
Mezzio\Router\RouteCollector
consumed by
Mezzio\Application
— in order to provide dynamic routing
capabilities to middleware. The interface serves as an abstraction to allow
routers with varying capabilities to be used with an application.
The interface is defined as follows:
namespace Mezzio\Router;
use Psr\Http\Message\ServerRequestInterface as Request;
/**
* Interface defining required router capabilities.
*/
interface RouterInterface
{
/**
* Add a route.
*
* This method adds a route against which the underlying implementation may
* match. Implementations MUST aggregate route instances, but MUST NOT use
* the details to inject the underlying router until `match()` and/or
* `generateUri()` is called. This is required to allow consumers to
* modify route instances before matching (e.g., to provide route options,
* inject a name, etc.).
*
* The method MUST raise Exception\RuntimeException if called after either `match()`
* or `generateUri()` have already been called, to ensure integrity of the
* router between invocations of either of those methods.
*
* @throws Exception\RuntimeException when called after match() or
* generateUri() have been called.
*/
public function addRoute(Route $route) : void;
/**
* Match a request against the known routes.
*
* Implementations will aggregate required information from the provided
* request instance, and pass them to the underlying router implementation;
* when done, they will then marshal a `RouteResult` instance indicating
* the results of the matching operation and return it to the caller.
*/
public function match(Request $request) : RouteResult;
/**
* Generate a URI from the named route.
*
* Takes the named route and any substitutions, and attempts to generate a
* URI from it. Additional router-dependent options may be passed.
*
* The URI generated MUST NOT be escaped. If you wish to escape any part of
* the URI, this should be performed afterwards; consider passing the URI
* to league/uri to encode it.
*
* @see https://github.com/auraphp/Aura.Router/blob/3.x/docs/generating-paths.md
* @see https://docs.laminas.dev/laminas-router/routing/
* @throws Exception\RuntimeException if unable to generate the given URI.
*/
public function generateUri(string $name, array $substitutions = [], array $options = []) : string;
}
Developers may create and use their own implementations. We recommend
registering your implementation as the service
Mezzio\Router\RouterInterface
in your container to ensure other
factories provided by mezzio will receive your custom service.
Implementors should also read the following sections detailing the Route
and
RouteResult
classes, to ensure that their implementations interoperate
correctly.
Routes
Routes are defined via Mezzio\Router\Route
, and aggregate the
following information:
- Path to match.
- Middleware to use when the route is matched. The value must implement
Psr\Http\Server\MiddlewareInterface
. - HTTP methods allowed for the route; if none are provided, all are assumed.
- Optionally, a name by which to reference the route.
The Route
class has the following signature:
namespace Mezzio\Router;
use Fig\Http\Message\RequestMethodInterface as RequestMethod;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class Route implements MiddlewareInterface
{
public const HTTP_METHOD_ANY = null;
public const HTTP_METHOD_SEPARATOR = ':';
/**
* @param string $path Path to match.
* @param MiddlewareInterface $middleware Middleware to use when this route is matched.
* @param null|string[] $methods Allowed HTTP methods; defaults to HTTP_METHOD_ANY.
* @param null|string $name the route name
*/
public function __construct(
string $path,
MiddlewareInterface $middleware,
array $methods = self::HTTP_METHOD_ANY,
string $name = null
);
/**
* Proxies to the middleware composed during instantiation.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface;
public function getPath() : string;
/**
* Set the route name.
*/
public function setName(string $name) : void;
public function getName() : string;
public function getMiddleware() : MiddlewareInterface;
/**
* @return null|string[] Returns HTTP_METHOD_ANY or array of allowed methods.
*/
public function getAllowedMethods() : ?array;
/**
* Indicate whether the specified method is allowed by the route.
*
* @param string $method HTTP method to test.
*/
public function allowsMethod(string $method) : bool;
public function setOptions(array $options) : void;
public function getOptions() : array;
}
Typically, developers will use the route()
method of either
Mezzio\Router\PathBasedRoutingMiddleware
or
Mezzio\Application
(or one of the HTTP-specific routing methods of
either class) to create routes, and will not need to interact with Route
instances. Additionally, when working with RouteResult
instances, you may
pull the Route
instance from that in order to obtain data about the matched
route.
Matching and RouteResults
Internally, routing middleware calls on RouterInterface::match()
,
passing it the current request instance. This allows implementations to pull
what they may need from the request in order to perform their routing logic; for
example, they may need the request method, the URI path, the value of the
HTTPS
server variable, etc.
Implementations are expected to return a Mezzio\Router\RouteResult
instance, which is then injected as a request attribute under the name
Mezzio\Router\RouteResult
when passing processing of the request to
the provided handler. Additionally, in the event of success, it will pull any
matched parameters from the result and inject them as request attributes as
well.
Dispatch middleware can then retrieve the route result from the request and process it, passing the route result its own request and handler.
The mezzio-router package also provides a number of middleware geared towards handling failed results which can be placed between routing and dispatch middleware:
-
Mezzio\Router\Middleware\MethodNotAllowedMiddleware
checks to see if the route failures was due to the HTTP method, and, if so, return a 405 response with an appropriateAllow
header. (read more) -
Mezzio\Router\Middleware\ImplicitHeadMiddleware
checks to see if a routing failure was due to a route match using aHEAD
request, and will then dispatch the appropriate route viaGET
request, and inject an empty body into the returned response. (read more) -
Mezzio\Router\Middleware\ImplicitOptionsMiddleware
checks to see if a routing failure was due to a route match using aOPTIONS
request; if so, it will return a 200 response with an appropriateAllow
header. (read more)
The RouteResult
signature is as follows:
namespace Mezzio\Router;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class RouteResult implements MiddlewareInterface
{
/**
* Create an instance representing a route succes from the matching route.
*
* @param array $params Parameters associated with the matched route, if any.
*/
public static function fromRoute(Route $route, array $params = []) : self;
/**
* Create an instance representing a route failure.
*
* @param null|array $methods HTTP methods allowed for the current URI, if any.
* null is equivalent to allowing any HTTP method; empty array means none.
*/
public static function fromRouteFailure(?array $methods) : self;
/**
* Process the result as middleware.
*
* If the result represents a failure, it passes handling to the handler.
*
* Otherwise, it processes the composed middleware using the provide request
* and handler.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface;
/**
* Does the result represent successful routing?
*/
public function isSuccess() : bool;
/**
* Retrieve the route that resulted in the route match.
*
* @return false|null|Route false if representing a routing failure;
* null if not created via fromRoute(); Route instance otherwise.
*/
public function getMatchedRoute();
/**
* Retrieve the matched route name, if possible.
*
* If this result represents a failure, return false; otherwise, return the
* matched route name.
*
* @return false|string
*/
public function getMatchedRouteName();
/**
* Returns the matched params.
*/
public function getMatchedParams() : array;
/**
* Is this a routing failure result?
*/
public function isFailure() : bool;
/**
* Does the result represent failure to route due to HTTP method?
*/
public function isMethodFailure() : bool;
/**
* Retrieve the allowed methods for the route failure.
*
* @return string[] HTTP methods allowed
*/
public function getAllowedMethods() : array;
}
Typically, only those implementing routers will interact with this class.