idealogica / route-one
PSR-15 route middleware for advanced middleware routing.
Requires
- php: >=7.0.0
- aura/router: ~3.1
- mindplay/middleman: ~3.0.3
- psr/container: ~1.0
- psr/http-message: ~1.0
- psr/http-server-handler: ~1.0.1
- psr/http-server-middleware: ~1.0.1
Requires (Dev)
- idealogica/debug: ~1.1
- laminas/laminas-diactoros: ~2.3.0
- phpunit/phpunit: ~7.5.20
README
The package is in the beta stage
route-one
is a PSR-15 compatible middleware aimed to
flexibly route a request to another middleware based on HTTP request url path, host, http method, etc.
It is built on top of Middleman and Aura.Router packages.
It's a good addition to your favorite middleware dispatcher to feel it more likely classical request router.
This package also contains a middleware dispatcher that has bunch of useful methods for easy creating route middleware instances.
route-one
is very similar to classic controller routers from every modern framework, but it has some more advantages:
- Standard compliant. You can use any PSR-15 compatible middleware. For example any of these: middlewares/psr15-middlewares.
- Allows to build multi-dimensional routes and modify response from a group of middleware.
- It makes your code highly reusable. Any part of the web resource can be bundled as a separate packaged middleware and used in other projects.
Installation
composer require idealogica/route-one:~0.1.0
General usage
// general dispatcher $dispatcher = DispatcherFactory::createDefault()->createDispatcher(); // page layout middleware $dispatcher->addMiddleware( function (ServerRequestInterface $request, DelegateInterface $next) { $response = $next->process($request); $content = $response->getBody()->getContents(); return $response ->withBody($this->streamFor('<html><body>' . $content . '</body></html>')) ->withHeader('content-type', 'text/html; charset=utf-8'); } ); // blog middleware $dispatcher->addMiddleware( function (ServerRequestInterface $request, DelegateInterface $next) { // blog middleware dispatcher $blogDispatcher = DispatcherFactory::createDefault()->createDispatcher(); $blogDispatcher->getDefaultRoute()->setHost('www.test.com')->setSecure(false); // blog posts list middleware (path based routing) $blogDispatcher->addGetRoute('/blog/posts', function (ServerRequestInterface $request, DelegateInterface $next) { // stop middleware chain execution return new Response($this->streamFor('<h1>Posts list</h1><p>Post1</p><p>Post2</p>')); } )->setName('blog.list'); // blog single post middleware (path based routing) $blogDispatcher->addGetRoute('/blog/posts/{id}', function (ServerRequestInterface $request, DelegateInterface $next) { $id = (int)$request->getAttribute('1.id'); // prefix for route-one attributes // post id is valid if ($id === 1) { // stop middleware chain execution return new Response($this->streamFor(sprintf('<h1>Post #%s</h1><p>Example post</p>', $id))); } // post not found, continue to the next middleware return $next->process($request); } )->setName('blog.post'); // blog page not found middleware (no routing, executes for each request) $blogDispatcher->addMiddleware( function (ServerRequestInterface $request, DelegateInterface $next) { // 404 response return new Response($this->streamFor('<h1>Page not found</h1>'), 404); } ); return $blogDispatcher->dispatch($request); } ); // dispatching $response = $dispatcher->dispatch( new ServerRequest( [], [], 'http://www.test.com/blog/posts/1', 'GET' ) ); (new SapiEmitter())->emit($response);
As you can see you can use callable as middleware. It is not a part of PSR-15 but it can be very helpful for quick prototyping.
Also you can use the route middleware separately with your own dispatcher:
$routeFactory = new RouteFactory( new AuraRouteMiddleware($basePath), new AuraUriGenerator($basePath) ); $routeMiddleware = $routeFactory->createGetRoute('/blog/posts', $middlewareToRoute);
For more information on routing rules configuration please refer to Aura.Router routes documentation.
Uri generation
You can use generator to create URIs based or your named routes. Example for the code above:
// route path is '/blog/posts/{id}' for 'blog.post' route $blogPostUrl = $blogDispatcher->getUriGenerator()->generate('blog.post', ['id' => 100]); echo($blogPostUrl); // outputs "http://www.test.com/blog/posts/100"
For more information on URIs generation please refer to Aura.Router generator documentation.
License
route-one is licensed under a MIT License.