-
Notifications
You must be signed in to change notification settings - Fork 4
Routing
← Middleware Component | Http Component →
Routing is one of the required components of Slytherin that stores HTTP routes (through RouterInterface
) and matches the result from the given HTTP method and URI through a dispatcher (DispatcherInterface
). The difference between a router and a dispatcher is explained carefully in this post.
Below code shows an example how the storing HTTP routes and dispatching them works:
namespace Rougin\Sample;
class Hello
{
public function greet()
{
return 'Hello world!';
}
}
// app/web/index.php
use Rougin\Slytherin\Routing\Dispatcher;
use Rougin\Slytherin\Routing\Router;
$router = new Router;
$router->get('/', 'Rougin\Sample\Hello@greet');
$dispatch = new Dispatcher($router);
$method = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
/** @var \Rougin\Slytherin\Routing\RouteInterface */
$route = $dispatch->dispatch($method, $uri);
The dispatch
method should return a RouteInterface
that contains the route details. If there is no route found against the specified $method
and $uri
, a BadMethodCallException
should be thrown.
There may be scenarios that a specified middleware can only be applied to a specified HTTP route. In such cases, the middleware must be added next to specifying its handler:
+use Psr\Http\Message\ResponseInterface;
use Rougin\Slytherin\Application;
+use Rougin\Slytherin\Sample\Handlers\Interop;
// ...
// Create a new HTTP route ---
-$app->get('/', function ()
+$fn = function (ResponseInterface $response)
{
- return 'Hello world!';
-});
+ return $response;
+};
+
+$app->get('/', $fn, new Interop);
// ---------------------------
// ...
When using middlewares, the output of a route handler should return in Psr\Http\Message\ResponseInterface
to apply the middleware's logic.
Tip
When using callbacks as route handlers, callbacks that return other than the ResponseInterface
will be automatically converted to the same interface.
Note
The code example above was based on the Using Application as a Router page.
The RoutingIntegration
can be used to define only the HTTP routes without manually specifying its dispatcher:
// app/web/index.php
// ...
use Rougin\Slytherin\Application;
use Rougin\Slytherin\Configuration;
use Rougin\Slytherin\Routing\Router;
use Rougin\Slytherin\Routing\RoutingIntegration;
// ...
$config = new Configuration;
// ...
// Create a new router to add an HTTP route... ---
$router = new Router;
$router->get('/', function ()
{
return 'Hello world!';
});
$config->set('app.router', $router);
// -----------------------------------------------
// ...then define it to a dispatcher ---
$items = array(new RoutingIntegration);
// -------------------------------------
$app = new Application;
echo $app->integrate($items)->run();
Note
The respective instance that will be created for the said integration is only limited for the third-party packages that are currently supported by Slytherin. The built-in implementation will be used if no third-party packages are installed for the said component.
If using the RoutingIntegration
, Slytherin can integrate the following third-party packages below if their respective packages are installed:
-
FastRouteDispatcher
,FastRouteRouter
- uses the FastRoute package by Nikita Popov (nikic/fast-route
) -
PhrouteDispatcher
,PhrouteRouter
- uses the Phroute package by Joe Green (phroute/phroute
)
If not using the supported packages above, a list of packages that handles HTTP routing are also listed at the awesome-php repository. Once selected a specified package, it must be implemented in DispatcherInterface
and RouterInterface
:
namespace Rougin\Slytherin\Routing;
interface DispatcherInterface
{
/**
* Dispatches against the provided HTTP method verb and URI.
*
* @param string $method
* @param string $uri
* @return \Rougin\Slytherin\Routing\RouteInterface
*
* @throws \BadMethodCallException
*/
public function dispatch($method, $uri);
/**
* Sets the router and parse its available routes if needed.
*
* @param \Rougin\Slytherin\Routing\RouterInterface $router
* @return self
*
* @throws \UnexpectedValueException
*/
public function setRouter(RouterInterface $router);
}
namespace Rougin\Slytherin\Routing;
interface RouterInterface
{
/**
* Adds a new raw route.
*
* @param string $method
* @param string $uri
* @param callable|string[]|string $handler
* @param \Rougin\Slytherin\Middleware\MiddlewareInterface[]|string[] $middlewares
* @return self
*/
public function add($method, $uri, $handler, $middlewares = array());
/**
* Merges a listing of parsed routes to current one.
*
* @param \Rougin\Slytherin\Routing\RouteInterface[] $routes
* @return self
*/
public function merge(array $routes);
/**
* Returns a listing of parsed routes.
*
* @param \Rougin\Slytherin\Routing\RouteInterface[] $routes
* @return mixed|null
*/
public function parsed(array $routes = array());
/**
* Returns a listing of available routes.
*
* @return \Rougin\Slytherin\Routing\RouteInterface[]
*/
public function routes();
}