-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from sunrise-php/release/v2.0.0
🎉 v2.0.0
- Loading branch information
Showing
114 changed files
with
8,119 additions
and
2,558 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
.php_cs.cache | ||
composer.lock | ||
coverage.xml | ||
phpbench.json | ||
phpcs.xml | ||
phpunit.xml | ||
vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,314 +1,81 @@ | ||
### Fast HTTP router with annotations support for PHP 7.1+ based on PSR-7 and PSR-15 | ||
## HTTP router for PHP 7.1+ based on PSR-7 and PSR-15<br>with support for annotations and OpenApi | ||
|
||
[![Gitter](https://badges.gitter.im/sunrise-php/support.png)](https://gitter.im/sunrise-php/support) | ||
[![Build Status](https://api.travis-ci.com/sunrise-php/http-router.svg?branch=master)](https://travis-ci.com/sunrise-php/http-router) | ||
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sunrise-php/http-router/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sunrise-php/http-router/?branch=master) | ||
[![Build Status](https://scrutinizer-ci.com/g/sunrise-php/http-router/badges/build.png?b=master)](https://scrutinizer-ci.com/g/sunrise-php/http-router/build-status/master) | ||
[![Code Coverage](https://scrutinizer-ci.com/g/sunrise-php/http-router/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/sunrise-php/http-router/?branch=master) | ||
[![Latest Stable Version](https://poser.pugx.org/sunrise/http-router/v/stable?format=flat)](https://packagist.org/packages/sunrise/http-router) | ||
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sunrise-php/http-router/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sunrise-php/http-router/?branch=master) | ||
[![Total Downloads](https://poser.pugx.org/sunrise/http-router/downloads?format=flat)](https://packagist.org/packages/sunrise/http-router) | ||
[![Latest Stable Version](https://poser.pugx.org/sunrise/http-router/v/stable?format=flat)](https://packagist.org/packages/sunrise/http-router) | ||
[![License](https://poser.pugx.org/sunrise/http-router/license?format=flat)](https://packagist.org/packages/sunrise/http-router) | ||
|
||
## Awards | ||
--- | ||
|
||
[![SymfonyInsight](https://insight.symfony.com/projects/62934e27-3e71-439c-9569-4aa57cdb3f36/big.svg)](https://insight.symfony.com/projects/62934e27-3e71-439c-9569-4aa57cdb3f36) | ||
|
||
## Benchmark (1k iterations with 1k routes) | ||
|
||
> [You can see it here](https://github.com/sunrise-php/http-router-benchmark) | ||
``` | ||
+-----------+------+--------------+-------+ | ||
| subject | its | mean | diff | | ||
+-----------+------+--------------+-------+ | ||
| Sunrise | 1000 | 17,856.609μs | 1.00x | | ||
| FastRoute | 1000 | 20,920.968μs | 1.17x | | ||
| Aura | 1000 | 44,480.588μs | 2.49x | | ||
| Zend | 1000 | 96,778.725μs | 5.42x | | ||
+-----------+------+--------------+-------+ | ||
``` | ||
|
||
## Installation (via composer) | ||
## Installation via composer | ||
|
||
```bash | ||
composer require sunrise/http-router | ||
composer require 'sunrise/http-router:^2.0' | ||
``` | ||
|
||
## How to use? | ||
|
||
Study [sunrise/awesome-skeleton](https://github.com/sunrise-php/awesome-skeleton) to understand how this can be used. | ||
|
||
#### Annotations | ||
## Examples of using | ||
|
||
> This package has annotation support, all the details are [here](https://github.com/sunrise-php/http-router-annotations-support). | ||
#### QuickStart | ||
|
||
> The example uses other sunrise packages, but you can use for example `zend/diactoros`, or any other. | ||
```bash | ||
composer require sunrise/http-message sunrise/http-server-request | ||
``` | ||
#### Strategy loading routes from configs | ||
|
||
```php | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
use Psr\Http\Server\MiddlewareInterface; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
use Sunrise\Http\Message\ResponseFactory; | ||
use Sunrise\Http\Router\Exception\MethodNotAllowedException; | ||
use Sunrise\Http\Router\Exception\RouteNotFoundException; | ||
use Sunrise\Http\Router\RouteCollection; | ||
use Sunrise\Http\Router\Loader\CollectableFileLoader; | ||
use Sunrise\Http\Router\Router; | ||
use Sunrise\Http\ServerRequest\ServerRequestFactory; | ||
|
||
class DemoMiddleware implements MiddlewareInterface | ||
{ | ||
public function process( | ||
ServerRequestInterface $request, | ||
RequestHandlerInterface $handler) : ResponseInterface | ||
{ | ||
$response = $handler->handle($request); | ||
|
||
$response->getBody()->write(sprintf('URI: "%s"; Attributes: "%s"', | ||
$request->getUri(), print_r($request->getAttributes(), true) | ||
)); | ||
|
||
return $response; | ||
} | ||
} | ||
|
||
$routes = new RouteCollection(); | ||
|
||
$routes->get('home', '/') | ||
->addMiddleware(new DemoMiddleware); | ||
|
||
$routes->group('/api', function($routes) | ||
{ | ||
$routes->group('/v1', function($routes) | ||
{ | ||
$routes->post('resource.create', '/resource') | ||
->addMiddleware(new DemoMiddleware); | ||
|
||
$routes->patch('resource.update', '/resource/{id}') | ||
->addPattern('id', '\d+') | ||
->addMiddleware(new DemoMiddleware); | ||
|
||
$routes->delete('resource.delete', '/resource/{id}') | ||
->addPattern('id', '\d+') | ||
->addMiddleware(new DemoMiddleware); | ||
|
||
$routes->get('resource.read', '/resource/{id}') | ||
->addPattern('id', '\d+') | ||
->addMiddleware(new DemoMiddleware); | ||
|
||
$routes->get('resource.all', '/resource') | ||
->addMiddleware(new DemoMiddleware); | ||
}); | ||
}); | ||
$loader = new CollectableFileLoader(); | ||
$loader->attach('routes/api.php'); | ||
$loader->attach('routes/admin.php'); | ||
$loader->attach('routes/public.php'); | ||
|
||
$router = new Router(); | ||
$router->addRoutes($routes); | ||
|
||
try | ||
{ | ||
$response = $router->handle(ServerRequestFactory::fromGlobals()); | ||
} | ||
catch (MethodNotAllowedException $e) | ||
{ | ||
$response = (new ResponseFactory)->createResponse(405) | ||
->withHeader('allow', implode(',', $e->getAllowedMethods())); | ||
|
||
$response->getBody()->write($response->getReasonPhrase()); | ||
} | ||
catch (RouteNotFoundException $e) | ||
{ | ||
$response = (new ResponseFactory)->createResponse(404); | ||
|
||
$response->getBody()->write($response->getReasonPhrase()); | ||
} | ||
$router->load($loader); | ||
|
||
$headers = $response->getHeaders(); | ||
// if the router is used as a request handler | ||
$response = $router->handle($request); | ||
|
||
foreach ($headers as $name => $values) | ||
{ | ||
foreach ($values as $value) | ||
{ | ||
header(sprintf('%s: %s', $name, $value), false); | ||
} | ||
} | ||
|
||
header(sprintf('HTTP/%s %d %s', | ||
$response->getProtocolVersion(), | ||
$response->getStatusCode(), | ||
$response->getReasonPhrase() | ||
), true); | ||
|
||
echo $response->getBody(); | ||
``` | ||
|
||
#### Adding a route to the collection | ||
|
||
###### Adds a new route to the collection | ||
|
||
```php | ||
$route = $routes->route('route.id', '/route/path', ['HEAD', 'GET']); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to HEAD requests | ||
|
||
```php | ||
$route = $routes->head('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to GET requests | ||
|
||
```php | ||
$route = $routes->get('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to POST requests | ||
|
||
```php | ||
$route = $routes->post('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to PUT requests | ||
|
||
```php | ||
$route = $routes->put('route.id', '/route/path'); | ||
// if the router is used as middleware | ||
$response = $router->process($request, $handler); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to PATCH requests | ||
#### Strategy loading routes from annotations | ||
|
||
```php | ||
$route = $routes->patch('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to DELETE requests | ||
|
||
```php | ||
$route = $routes->delete('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to PURGE requests | ||
|
||
```php | ||
$route = $routes->purge('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to safe requests | ||
|
||
```php | ||
$route = $routes->safe('route.id', '/route/path'); | ||
``` | ||
|
||
###### Adds a new route to the collection that will respond to any requests | ||
|
||
```php | ||
$route = $routes->any('route.id', '/route/path'); | ||
``` | ||
|
||
#### Route grouping | ||
|
||
```php | ||
// Add a route to the collection with the path: /foo/bar/baz/qux | ||
$routes->group('/foo', function($routes) | ||
{ | ||
$routes->group('/bar', function($routes) | ||
{ | ||
$routes->group('/baz', function($routes) | ||
{ | ||
$route = $routes->get('qux', '/qux'); | ||
}); | ||
}); | ||
}); | ||
``` | ||
|
||
#### Route patterns | ||
|
||
```php | ||
$route = $routes->any('resource.action', '/resource/{action}(/{id})') | ||
->addPattern('action', 'create|update|delete|read|all') | ||
->addPattern('id', '\d+'); | ||
``` | ||
|
||
#### Route middlewares | ||
|
||
```php | ||
$route | ||
->addMiddleware(new FooMiddleware) | ||
->addMiddleware(new BarMiddleware) | ||
->addMiddleware(new BazMiddleware); | ||
``` | ||
|
||
#### Router middlewares | ||
|
||
```php | ||
$router | ||
->addMiddleware(new FooMiddleware) | ||
->addMiddleware(new BarMiddleware) | ||
->addMiddleware(new BazMiddleware); | ||
``` | ||
|
||
#### Router matching | ||
|
||
```php | ||
$route = $router->match($request); | ||
``` | ||
|
||
## Useful Middlewares | ||
|
||
#### Error handling ([whoops](https://github.com/filp/whoops)) | ||
use Doctrine\Common\Annotations\AnnotationRegistry; | ||
use Sunrise\Http\Router\Loader\AnnotationDirectoryLoader; | ||
use Sunrise\Http\Router\Router; | ||
|
||
```bash | ||
composer require middlewares/whoops | ||
``` | ||
AnnotationRegistry::registerLoader('class_exists'); | ||
|
||
```php | ||
$router->addMiddleware(new \Middlewares\Whoops()); | ||
``` | ||
$loader = new AnnotationDirectoryLoader(); | ||
$loader->attach('src/Http/RequestHandler'); | ||
|
||
#### Payload ([payload](https://github.com/middlewares/payload)) | ||
$router = new Router(); | ||
$router->load($loader); | ||
|
||
```bash | ||
composer require middlewares/payload | ||
``` | ||
// if the router is used as a request handler | ||
$response = $router->handle($request); | ||
|
||
```php | ||
$router->addMiddleware(new \Middlewares\JsonPayload()); | ||
$router->addMiddleware(new \Middlewares\UrlEncodePayload()); | ||
// if the router is used as middleware | ||
$response = $router->process($request, $handler); | ||
``` | ||
|
||
#### Encoding ([encoder](https://github.com/middlewares/encoder)) | ||
|
||
```bash | ||
composer require middlewares/encoder | ||
``` | ||
#### Without loading strategy | ||
|
||
```php | ||
$router->addMiddleware(new \Middlewares\GzipEncoder()); | ||
``` | ||
use App\Http\RequestHandler\HomeRequestHandler; | ||
use Sunrise\Http\Router\RouteCollector; | ||
use Sunrise\Http\Router\Router; | ||
|
||
## Awesome PSR-15 Middlewares | ||
$collector = new RouteCollector(); | ||
$collector->get('home', '/', new HomeRequestHandler()); | ||
|
||
https://github.com/middlewares | ||
$router = new Router(); | ||
$router->addRoute(...$collector->getCollection()->all()); | ||
|
||
## Test run | ||
// if the router is used as a request handler | ||
$response = $router->handle($request); | ||
|
||
```bash | ||
php vendor/bin/phpunit | ||
// if the router is used as middleware | ||
$response = $router->process($request, $handler); | ||
``` | ||
|
||
## Benchmark run | ||
|
||
https://github.com/sunrise-php/http-router-benchmark | ||
|
||
## Api documentation | ||
|
||
https://phpdoc.fenric.ru/ | ||
|
||
## Useful links | ||
|
||
* https://www.php-fig.org/psr/psr-7/ | ||
* https://www.php-fig.org/psr/psr-15/ | ||
* https://github.com/middlewares |
Empty file.
Oops, something went wrong.