Application

Learn all about the default middleware dispatcher in BitFrame

Middleware Dispatcher

Dispatching Middleware:

Middleware can be run in BitFrame in two ways:

  1. By adding middleware to the middleware dispatcher queue and running it at a later time;
  2. By immediately invoking the specified middlewares.

Both these methods rely on calling the run() method on the \BitFrame\Application instance.

Either of these techniques can be used to nest middleware, no matter how many levels deep you wish to nest them. You can read more about nesting in the Middleware Dispatcher section.

Queuing and Running Middleware:

You can add any number of middleware(s) to the middleware queue by using the addMiddleware() method on \BitFrame\Application instance. Once you wish to execute these middlewares, you can do so by calling the run() method on the \BitFrame\Application instance, for example:

$app = new \BitFrame\Application;

/* add a middleware  */
$app->addMiddleware([
    $middleware1,
    $middleware2,
    // ...
]);

// run middleware
$app->run();
Immediately Invoking Middleware:

If you wish to execute the middlewares as soon as they're added to the queue, you can do so by passing the middleware(s) to the run() method like so:

$app = new \BitFrame\Application;

// run middleware
$app->run([
    $middleware1,
    $middleware2,
    // ...
]);
Nesting Middleware

You may queue up nested middleware like so:

$app = new \BitFrame\Application;

$app
    ->addMiddleware([
        // ...,
        function ($request, $response, $next) use (&$app) {
            $response->getBody()->write('1;');

            $app->addMiddleware([
                function ($request, $response, $next) {
                    $response->getBody()->write('2;');

                    return $next($request, $response);
                },
                function ($request, $response, $next) {
                    $response->getBody()->write('3;');

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

            return $next($request, $response);
        }
    ])
    ->run();

// output: '1;2;3;'

Or you may even immediately invoke nested middleware like so:

$app = new \BitFrame\Application;

$app->run([
    // ...,
    function ($request, $response, $next) use (&$app) {
        $response->getBody()->write('1;');

        $app->run([
            function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
                $response->getBody()->write('2;');

                return $next($request, $response);
            },
            function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
                $response->getBody()->write('3;');

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

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

// output: '1;2;3;'

It's important to remember that immediately invoked middleware will run at once, and the middleware you add via addMiddleware() method will be added to the end of the middleware queue (which means it will be executed last).

Default Events:

The following event name contants can be accessed on the \BitFrame\Dispatcher\MiddlewareDispatcher class:

  1. MiddlewareDispatcher::EVENT_BEFORE_DISPATCH: triggered before a middleware is executed;
  2. MiddlewareDispatcher::EVENT_AFTER_DISPATCH: triggered after a middleware has been executed;
  3. MiddlewareDispatcher::EVENT_DONE_DISPATCH: triggered once the middleware finished processing.

You can listen for these events on the \BitFrame\Application instance like so:

use \BitFrame\Dispatcher\MiddlewareDispatcher;

$app = new \BitFrame\Application;

$app->attach(MiddlewareDispatcher::EVENT_BEFORE_DISPATCH, function($event) {
    /*  */
});

Although these events are triggered by the middleware dispatcher object, the reason we can attach event listeners via the \BitFrame\Application object is because the application object itself is an event manager and implements \BitFrame\EventManager\EventManagerInterface.

Middleware Exceptions:

The following exceptions are thrown by \BitFrame\Dispatcher\MiddlewareDispatcher (which is the default middleware dispatcher used by \BitFrame\Application):

  • 400: \BitFrame\Exception\BadRequestException
  • 401: \BitFrame\Exception\UnauthorizedException
  • 403: \BitFrame\Exception\ForbiddenException
  • 404: \BitFrame\Exception\RouteNotFoundException
  • 405: \BitFrame\Exception\MethodNotAllowedException
  • 500: \BitFrame\Exception\InternalErrorException
  • 501: \BitFrame\Exception\NotImplementedException
  • 503: \BitFrame\Exception\ServiceUnavailableException
  • Others: \BitFrame\Exception\HttpException
  • PHP Errors: \BitFrame\Exception\ErrorException

Comments

Let us know if you have something to say or add