How To

Learn how to setup routes in BitFrame Microframework

Setup Routes

Using A Route Collection

\BitFrame\Application does not come bundled with a default http router because:

  1. We want you to have the freedom to choose any router you want;
  2. Some projects might not need a router, for example single page prototypes, apps, etc.

Instead \BitFrame\Application implements \BitFrame\Router\RouteCollectionInterface which means it comes with methods that allow us to store routes on classes that implement it, for example:

$app = new \BitFrame\Application;

$app->get('/hello/{name}', function ($request, $response, $next) {
    $name = $request->getAttribute('name');
    $response->getBody()->write("Hello, $name");

    return $next($request, $response);
});

As mentioned before, all this does is, store the route as a \BitFrame\Router\RouteCollection object which is passed along the http request object as \BitFrame\Router\RouteCollection attribute and can be used to easily access route data, for example:

use \BitFrame\Router\RouteCollection;

// if no routes found, default to []
$appRoutes = $request->getAttribute(RouteCollectionInterface::class, []);

if (! empty($appRoutes)) {
    foreach ($appRoutes->getData() as $route) {
        // $route->getMethods(); e.g. GET, POST, etc.
        // $route->getPath(); route path
        // $route->getCallable(); route handler/callback
    }
}

These routes can easily be picked up by a router middleware (such as \BitFrame\Router\FastRouteRouter) which can then process it.

The ability to store routes on \BitFrame\Application instance was added as a convenience, and to offer functionality to be able to store route data on application instance without worrying about the particular router being used. However, you are free to use a router's own methods should you wish.

A complete example of how to setup routes with a router middleware, such as \BitFrame\Router\FastRouteRouter for example, would look like this:

require '../vendor/autoload.php';

$app = new \BitFrame\Application;

$app->get('/hello/{name}', function ($request, $response, $next) {
    $name = $request->getAttribute('name');
    $response->getBody()->write("Hello, $name");

    return $next($request, $response);
});

$app->run([
    \BitFrame\Message\DiactorosResponseEmitter::class,
    \BitFrame\Router\FastRouteRouter::class
]);

As you may have noticed, we've included a Response Emitter middleware, which is essential to output the response from all middlewares.

\BitFrame\Message\DiactorosResponseEmitter and \BitFrame\Router\FastRouteRouter are external packages and must be included in your application before you can use them. You are, of course, not bound to use these particular packages and can easily use other alternatives in their place.

Using \BitFrame\Delegate\RoutesDelegate

We've introduced a new \BitFrame\Delegate\RoutesDelegate class in BitFrame v1.0.9 that allows you to define route definitions in one place and easily inject them into a route collection.

Routes Configuration Array Syntax:
$routes = [
    [
        // optional (default: 'GET')
        'method' => ['GET', 'POST'],

        // optional (default: '/')
        'path' => '/path/to/match',

        // required
        'controller' => '\App\Service\Controller::index'
    ],
    // etc.
];

To define a route in this way, you must to the very least define a controller which must be a callable (see our guide on handling routes to see various different ways of defining a controller).

A path, if not defined defaults to '/' and if method key is undefined, it defaults to 'GET'.

Adding Routes:

To add routes from a configuration array, we simply call the RoutesDelegate::fromConfig() method that takes in the following two arguments:

  1. A class implementing \BitFrame\Router\RouteCollectionInterface as the first argument (such as \BitFrame\Application and \BitFrame\Router\FastRouteRouter)
  2. A routes configuration array as the second argument.

Here's a complete example:

require '../vendor/autoload.php';

// 1: class implementing RouteCollectionInterface
$app = new \BitFrame\Application;

/* 2: define a controller class */

// 3: define routes
$routes = [
    [
        'method' => ['GET', 'POST'],
        'path' => '/path/to/match',
        'controller' => '\App\Service\Controller::index'
    ],
    // etc.
];

// 4: delegate routes to route collection from configuration array
\BitFrame\Delegate\RoutesDelegate::fromConfig($app, $routes);

See our guide on handling routes to see various different ways of defining a controller.

Comments

Let us know if you have something to say or add