Skip to content

Commit 0d87530

Browse files
committed
Update documentation, added shortcuts method to create Middleware from callable.
1 parent 78c1832 commit 0d87530

12 files changed

+393
-51
lines changed

README.md

Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,110 @@ Lightweight & simple PSR-15 server request handler implementation to handle midd
1313
Request handler implementing the [RequestHandlerInterface](https://github.com/php-fig/http-server-handler/blob/master/src/RequestHandlerInterface.php)
1414
and able to manage a collection of middlewares implementing the [MiddlewareInterface](https://github.com/php-fig/http-server-middleware/blob/master/src/MiddlewareInterface.php).
1515

16-
This middleware attempts to provide interoperability to process a collection of middlewares and
17-
give the possibility to define the strategy on how middlewares are fetched.
16+
This request handler attempts to provide interoperability to process a collection of middlewares and
17+
give the possibility to define the strategy on how middlewares will be processed.
1818

1919
### Getting started
2020

21+
#### Requirements
22+
23+
- PHP 7.3
24+
2125
#### Installation
2226

2327
`composer require noglitchyo/middleware-collection-request-handler`
2428

2529
#### Run
2630

27-
The RequestHandler class only need 2 arguments:
28-
29-
- A default request handler (implementing [RequestHandlerInterface](https://github.com/php-fig/http-server-handler/blob/master/src/RequestHandlerInterface.php))
31+
Instantiate the RequestHandler class. It requires ony 2 arguments:
3032

31-
It is there to provide the response if no middleware created one.
32-
For example, you are using ADR pattern, the default request handler might be your Action.
33-
It is also possible to directly provide a `callable` using `RequestHandler::fromCallable()`.
34-
It will generate a generic instance of RequestHandlerInterface wrapping the `callable` inside.
33+
- `$defaultRequestHandler` ([RequestHandlerInterface](https://github.com/php-fig/http-server-handler/blob/master/src/RequestHandlerInterface.php))
3534

36-
***Remember: the default request handler is responsible for providing a default response.***
35+
***The default request handler is responsible to provide a default response if none of the middlewares created one.***
3736

38-
- A middleware collection (implementing [MiddlewareCollectionInterface](https://github.com/noglitchyo/middleware-collection-request-handler/blob/master/src/MiddlewareCollectionInterface.php))
37+
Some examples of "default request handler":
38+
- with the [ADR pattern](https://en.wikipedia.org/wiki/Action%E2%80%93domain%E2%80%93responder), the default request handler might be your action class.
39+
- with the [MVC pattern](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), the default request handler might be the action method of your controller.
3940

40-
It defines how you store your middlewares and the strategy to retrieve them.
41-
Some implementations are provided by default and will probably fit your needs.
42-
They offers different strategies varying from the Stack to the Queue.
41+
It is possible to directly provide a `callable` using the factory method `RequestHandler::fromCallable()`.
42+
It will generate a generic instance of RequestHandlerInterface wrapping the `callable` inside.
4343

44-
However, it is really simple to create you own collection if needed, since MiddlewareCollectionInterface requires only 3 methods.
44+
- `$middlewareCollection` ([MiddlewareCollectionInterface](https://github.com/noglitchyo/middleware-collection-request-handler/blob/master/src/MiddlewareCollectionInterface.php))
45+
46+
Contains the middlewares and encapsulate the strategy used to store and retrieve the middlewares.
47+
Some standard implementations are provided with different strategies: [stack (LIFO)](https://github.com/noglitchyo/middleware-collection-request-handler/blob/master/src/Collection/SplStackMiddlewareCollection.php), [queue (FIFO)](https://github.com/noglitchyo/middleware-collection-request-handler/blob/master/src/Collection/SplQueueMiddlewareCollection.php).
48+
49+
##### Example
50+
51+
Below, this is how simple it is to get your middleware stack running:
52+
53+
```php
54+
<?php
55+
56+
use NoGlitchYo\MiddlewareCollectionRequestHandler\RequestHandler;
57+
use NoGlitchYo\MiddlewareCollectionRequestHandler\Collection\SplStackMiddlewareCollection;
58+
use Psr\Http\Server\MiddlewareInterface;
59+
use Psr\Http\Message\ServerRequestInterface;
60+
use Psr\Http\Server\RequestHandlerInterface;
61+
use Psr\Http\Message\ResponseInterface;
62+
63+
// Instantiate a collection of middleware.
64+
$middlewareCollection = new SplStackMiddlewareCollection([
65+
new class implements MiddlewareInterface{
66+
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface{
67+
$handler->handle($request);
68+
}
69+
}
70+
]);
71+
72+
// Instantiate a new request handler with a default handler and the middleware collection.
73+
$requestHandler = RequestHandler::fromCallable(
74+
function (ServerRequestInterface $serverRequest){
75+
return new /* instance of ResponseInterface */;
76+
},
77+
$middlewareCollection
78+
);
79+
80+
// Pass the request to the request handler.
81+
$response = $requestHandler->handle(/* ServerRequestInterface */);
82+
83+
```
84+
85+
#### Create a custom MiddlewareCollectionInterface implementation
86+
87+
It is easy to create you own MiddlewareCollectionInterface implementation if you need. The interface requires only 3 methods:
88+
```php
89+
<?php
90+
interface MiddlewareCollectionInterface
91+
{
92+
/**
93+
* Must return true if there is no middleware in the collection to process.
94+
* @return bool
95+
*/
96+
public function isEmpty(): bool;
97+
98+
/**
99+
* Must return the next middleware to process in the collection.
100+
* Depending on the implemented strategy, the middleware MAY not be removed from the collection.
101+
* @return MiddlewareInterface
102+
*/
103+
public function next(): MiddlewareInterface;
104+
105+
/**
106+
* Add a middleware instance of MiddlewareInterface to the collection.
107+
*
108+
* @param MiddlewareInterface $middleware
109+
*
110+
* @return MiddlewareCollectionInterface
111+
*/
112+
public function add(MiddlewareInterface $middleware): MiddlewareCollectionInterface;
113+
}
114+
```
45115

46116
#### Tests
47117

118+
Would like to the run the test suite? Go ahead:
119+
48120
`composer test`
49121

50122
### References
@@ -53,4 +125,4 @@ https://www.php-fig.org/psr/psr-15/
53125

54126
## License
55127

56-
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
128+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
"scripts": {
3434
"phpstan": "phpstan analyse -l max src",
3535
"phpcs": "phpcs --standard=PSR2 ./src/",
36-
"test": "phpunit phpunit.dist.xml"
36+
"test": "phpunit -c phpunit.xml.dist"
3737
}
3838
}

src/Collection/ArrayStackMiddlewareCollection.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types=1);
1+
<?php
22
/**
33
* MIT License
44
*
@@ -22,15 +22,19 @@
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
* SOFTWARE.
2424
*/
25+
declare(strict_types=1);
2526

2627
namespace NoGlitchYo\MiddlewareCollectionRequestHandler\Collection;
2728

2829
use NoGlitchYo\MiddlewareCollectionRequestHandler\Exception\EmptyMiddlewareCollectionException;
2930
use NoGlitchYo\MiddlewareCollectionRequestHandler\MiddlewareCollectionInterface;
31+
use NoGlitchYo\MiddlewareCollectionRequestHandler\MiddlewareCollectionTrait;
3032
use Psr\Http\Server\MiddlewareInterface;
3133

3234
class ArrayStackMiddlewareCollection implements MiddlewareCollectionInterface
3335
{
36+
use MiddlewareCollectionTrait;
37+
3438
/**
3539
* @var MiddlewareInterface[]
3640
*/
@@ -68,4 +72,11 @@ public function add(MiddlewareInterface $middleware): MiddlewareCollectionInterf
6872

6973
return $this;
7074
}
75+
76+
public function addFromCallable(callable $callable): MiddlewareCollectionInterface
77+
{
78+
$this->add(self::createFromCallable($callable));
79+
80+
return $this;
81+
}
7182
}

src/Collection/SplQueueMiddlewareCollection.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types=1);
1+
<?php
22
/**
33
* MIT License
44
*
@@ -22,17 +22,21 @@
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
* SOFTWARE.
2424
*/
25+
declare(strict_types=1);
2526

2627
namespace NoGlitchYo\MiddlewareCollectionRequestHandler\Collection;
2728

2829
use NoGlitchYo\MiddlewareCollectionRequestHandler\Exception\EmptyMiddlewareCollectionException;
2930
use NoGlitchYo\MiddlewareCollectionRequestHandler\MiddlewareCollectionInterface;
31+
use NoGlitchYo\MiddlewareCollectionRequestHandler\MiddlewareCollectionTrait;
3032
use Psr\Http\Server\MiddlewareInterface;
3133
use RuntimeException;
3234
use SplQueue;
3335

3436
class SplQueueMiddlewareCollection implements MiddlewareCollectionInterface
3537
{
38+
use MiddlewareCollectionTrait;
39+
3640
/**
3741
* @var SplQueue
3842
*/
@@ -73,4 +77,11 @@ public function add(MiddlewareInterface $middleware): MiddlewareCollectionInterf
7377

7478
return $this;
7579
}
80+
81+
public function addFromCallable(callable $callable): MiddlewareCollectionInterface
82+
{
83+
$this->add(self::createFromCallable($callable));
84+
85+
return $this;
86+
}
7687
}

src/Collection/SplStackMiddlewareCollection.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types=1);
1+
<?php
22
/**
33
* MIT License
44
*
@@ -22,17 +22,21 @@
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
* SOFTWARE.
2424
*/
25+
declare(strict_types=1);
2526

2627
namespace NoGlitchYo\MiddlewareCollectionRequestHandler\Collection;
2728

2829
use NoGlitchYo\MiddlewareCollectionRequestHandler\Exception\EmptyMiddlewareCollectionException;
2930
use NoGlitchYo\MiddlewareCollectionRequestHandler\MiddlewareCollectionInterface;
31+
use NoGlitchYo\MiddlewareCollectionRequestHandler\MiddlewareCollectionTrait;
3032
use Psr\Http\Server\MiddlewareInterface;
3133
use RuntimeException;
3234
use SplStack;
3335

3436
class SplStackMiddlewareCollection implements MiddlewareCollectionInterface
3537
{
38+
use MiddlewareCollectionTrait;
39+
3640
/**
3741
* @var SplStack
3842
*/
@@ -73,4 +77,11 @@ public function next(): MiddlewareInterface
7377
throw new EmptyMiddlewareCollectionException();
7478
}
7579
}
80+
81+
public function addFromCallable(callable $callable): MiddlewareCollectionInterface
82+
{
83+
$this->add(self::createFromCallable($callable));
84+
85+
return $this;
86+
}
7687
}

src/MiddlewareCollectionInterface.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types=1);
1+
<?php
22
/**
33
* MIT License
44
*
@@ -22,6 +22,7 @@
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
* SOFTWARE.
2424
*/
25+
declare(strict_types=1);
2526

2627
namespace NoGlitchYo\MiddlewareCollectionRequestHandler;
2728

@@ -35,9 +36,25 @@
3536
*/
3637
interface MiddlewareCollectionInterface
3738
{
39+
/**
40+
* Must return true if there is no middleware in the collection to process.
41+
* @return bool
42+
*/
3843
public function isEmpty(): bool;
3944

45+
/**
46+
* Must return the next middleware to process in the collection.
47+
* Depending on the implemented strategy, the middleware MAY not be removed from the collection.
48+
* @return MiddlewareInterface
49+
*/
4050
public function next(): MiddlewareInterface;
4151

52+
/**
53+
* Add a middleware instance of MiddlewareInterface to the collection.
54+
*
55+
* @param MiddlewareInterface $middleware
56+
*
57+
* @return MiddlewareCollectionInterface
58+
*/
4259
public function add(MiddlewareInterface $middleware): MiddlewareCollectionInterface;
4360
}

src/MiddlewareCollectionTrait.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
/**
3+
* MIT License
4+
*
5+
* Copyright (c) 2019 Maxime Elomari
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
* SOFTWARE.
24+
*/
25+
declare(strict_types=1);
26+
27+
namespace NoGlitchYo\MiddlewareCollectionRequestHandler;
28+
29+
use Psr\Http\Message\ResponseInterface;
30+
use Psr\Http\Message\ServerRequestInterface;
31+
use Psr\Http\Server\MiddlewareInterface;
32+
use Psr\Http\Server\RequestHandlerInterface;
33+
34+
trait MiddlewareCollectionTrait
35+
{
36+
private static function createFromCallable(callable $callable): MiddlewareInterface
37+
{
38+
return new class($callable) implements MiddlewareInterface
39+
{
40+
private $callable;
41+
42+
public function __construct(callable $callable)
43+
{
44+
$this->callable = $callable;
45+
}
46+
47+
public function process(
48+
ServerRequestInterface $request,
49+
RequestHandlerInterface $handler
50+
): ResponseInterface {
51+
return call_user_func($this->callable, $request, $handler);
52+
}
53+
};
54+
}
55+
}

src/RequestHandler.php

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types=1);
1+
<?php
22
/**
33
* MIT License
44
*
@@ -22,6 +22,7 @@
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
* SOFTWARE.
2424
*/
25+
declare(strict_types=1);
2526

2627
namespace NoGlitchYo\MiddlewareCollectionRequestHandler;
2728

@@ -31,6 +32,8 @@
3132

3233
class RequestHandler implements RequestHandlerInterface
3334
{
35+
use RequestHandlerTrait;
36+
3437
/**
3538
* @var MiddlewareCollectionInterface
3639
*/
@@ -72,22 +75,4 @@ public function handle(ServerRequestInterface $request): ResponseInterface
7275

7376
return $nextMiddleware->process($request, $this);
7477
}
75-
76-
private static function createRequestHandlerFromCallable(callable $callable): RequestHandlerInterface
77-
{
78-
return new class($callable) implements RequestHandlerInterface
79-
{
80-
private $callable;
81-
82-
public function __construct(callable $callable)
83-
{
84-
$this->callable = $callable;
85-
}
86-
87-
public function handle(ServerRequestInterface $request): ResponseInterface
88-
{
89-
return call_user_func($this->callable, $request);
90-
}
91-
};
92-
}
9378
}

0 commit comments

Comments
 (0)