Zend Stratigility Enhancement

zend-stratigility

#1

Recently i noticed in node.js they use a sub process to calling another middleware.

router.use(function(req, res, next) {
    if (!req.route)
        return next (new Error('404'));  
    next();
});

What do you think about implement this feature into Zend Stratigiliy ?

I use this feature in my library

Look at the process method
https://github.com/obullo/Middleware/blob/master/src/Next.php

And Router middleware
https://github.com/obullo/Middleware/blob/master/demo/classes/App/Middleware/Router.php


#2

The Next implementation you link to is very similar to how we plan to implement it in v3 (see our refactor patch for details).

Unfortunately, the Router link you have above does not resolve, and I cannot find it within that particular repository, so if that contains additional information, I need a new link. :slight_smile:


#3

Yes I guess its similar, Sorry for broken link :slight_smile: here is the full code.

namespace App\Middleware;

class Error implements MiddlewareInterface
{
    protected $err;
    protected $errResponse;

    public function __construct($err = null)
    {
        if (is_string($err)) {
            switch ($err) {
                case '404':
                $this->errResponse = new HtmlResponse($this->render404Error(), 404);
                    break;
                default:
                $this->errResponse = new HtmlResponse($this->renderHtmlErrorMessage($err), 404);
                    break;
            }
        }
    }

    public function process(Request $request, RequestHandler $handler) : ResponseInterface
    {
        if ($this->errResponse != null) {
            return $this->errResponse;
        }
        try {
            $response = $handler->handle($request);
        } catch (Throwable $throwable) { 
            $response = $this->handleError($throwable);
        } catch (Exception $exception) {
            $response = $this->handleError($throwable);
        }
        return $response;
    }

    protected function handleError($error)
    {
        $html = $this->renderHtmlErrorMessage($error);
        // $json = $this->renderJsonErrorMessage($error);
        
        if (is_object($error)) {
            switch ($error) {
                case ($error instanceof Throwable):
                case ($error instanceof Exception):
                case ($error instanceof RuntimeException):
                    // error log
                    break;
            }
        }
        // return new JsonResponse($json, 500, [], JSON_PRETTY_PRINT);

        return new HtmlResponse($html, 500);
    }
}


namespace App\Middleware;

class Router implements MiddlewareInterface
{
    public function process(Request $request, RequestHandler $handler) : ResponseInterface
    {
        $match = false;
        if (! $match) {
            return $handler->process(new Error('404'));
        }
        return new HtmlResponse('Hello World !');
    }
}


use App\Middleware\Error;
use App\Middleware\Router;
use Obullo\Middleware\Dispatcher;

$request = Zend\Diactoros\ServerRequestFactory::fromGlobals();

$dispatcher = new Dispatcher;
$handler = $dispatcher->withMiddleware(new Error)  // Error middleware must be initialize at the top.
    ->withMiddleware(new Router);

$response = $handler->process($request);

#4

Stratigility does not provide routing capabilities; it is a middleware dispatching library, full stop.

For handling errors, we already have Zend\Expressive\Middleware\ErrorHandler, which provides a way both to report errors as well as log them; the reporting capabilities can be customized (see the docs), allowing you to respond in HTML, JSON, XML, or any other format you want.

For routing, we provide zend-expressive-router, which provides a router interface for handling PSR-7 requests and matching them to middleware. zend-expressive has built-in routing middleware that then consumes it, and separate dispatch middleware that actually dispatches the matched middleware.

Finally, when all is said and done, if unable to match a route, we pipe in a “NotFoundHandler”, which returns a templated 404 response.

What you provide above we feel is outside the scope of Stratigility, but fully within the scope of Expressive (which is a middleware framework), and is very similar to how we handle it there.