Skip to content

Commit ba0e033

Browse files
committed
ADDED: PSR related documentation. Other refactoring.
1 parent b131117 commit ba0e033

File tree

1 file changed

+58
-11
lines changed

1 file changed

+58
-11
lines changed

README.md

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
## Introduction:
1+
## Introduction
22

33
Pipeline follows the Chain of Responsibility Design Pattern to handle the given subject/request using pipes.
44

5-
## Documentation
6-
7-
### Installation (via Composer)
5+
## Installation (via Composer)
86

97
Install library using composer command:
108
```sh
119
$ composer require thewebsolver/pipeline
1210
```
1311

14-
### Usage
12+
## Usage
1513

16-
The main responsibility of the Pipeline class is to pass given subject to all registered pipes and return back the transformed value. The pipeline chain can be initialised following builder pattern as follows:
14+
The main responsibility of the Pipeline class is to pass given subject to all registered pipes and return back the transformed value. The pipeline chain can be initialized following builder pattern as follows:
1715
- Initialize the pipeline (`new Pipeline()`).
1816
- Pass subject to the pipeline using `Pipeline::send()` method.
1917
- Provide a single handler using `Pipeline::pipe()` method or if multiple pipes (_which obviously should be the case, otherwise what is the intent of using Pipeline anyway_), use `Pipeline::through()` method.
20-
> NOTE: `Pipeline::through()` is the main method to provide pipes. If pipes are provided using `Pipeline::pipe()` method and then required pipes are provided using `Pipeline::through()` method, pipes provided using `Pipeline::pipe()` will be defered. Meaning subject will pass through pipes provided using `Pipeline::through()` and then the transformed subject is pass through other pipes provided using `Pipeline::pipe()`.
18+
> NOTE: `Pipeline::through()` is the main method to provide pipes. If pipes are provided using `Pipeline::pipe()` method and then required pipes are provided using `Pipeline::through()` method, pipes provided using `Pipeline::pipe()` will be deferred. Meaning subject will pass through pipes provided using `Pipeline::through()` and then the transformed subject is pass through other pipes provided using `Pipeline::pipe()`.
2119

2220
> In summary, `Pipeline::pipe()` method's intent is to append additional pipes to the pipeline after required pipes are provided using `Pipeline::through()` method.
2321

@@ -29,7 +27,7 @@ There are two methods that may be required depending on how subject is being han
2927
- `Pipeline::use()` method provides additional data to each pipe.
3028
- `Pipeline::sealWith()` method provides prevention mechanism form script interruption if any pipe throws an exception.
3129

32-
#### Basic Usage
30+
### Basic Usage
3331
```php
3432
use TheWebSolver\Codegarage\Lib\Pipeline;
3533

@@ -43,15 +41,15 @@ class MakeTextUpperCase implements PipeInterface {
4341
// Pipe as a lambda function.
4442
$trimCharacters = static fn(string $text, \Closure $next): string => $next( trim( $text ) );
4543

46-
// $finalText will be -> 'WHITESPACED AND MIXED CASED STRING';
44+
// $finalText will be -> 'WHITESPACE AND MIXED CASED STRING';
4745
$finalText = (new Pipeline())
48-
->send(subject: ' Whitespaced and Mixed cased String\ ')
46+
->send(subject: ' Whitespace and Mixed cased String\ ')
4947
->through(pipes: array( MakeTextUpperCase::class, $trimCharacters ) )
5048
->thenReturn();
5149
```
5250

5351

54-
#### Advanced Usage
52+
### Advanced Usage
5553
```php
5654
use Closure;
5755
use Throwable;
@@ -92,3 +90,52 @@ $transformed = $pipeline->then(
9290
static fn(mixed $subject) => array('prefix', ...(is_array($subject) ? $subject : array()))
9391
);
9492
```
93+
94+
## PSR-7 & PSR-15 Bridge
95+
The `TheWebSolver\Codegarage\Lib\PipelineBridge` seamlessly handles middlewares coming to the Request Handler, piping through the pipeline and getting the response back.
96+
97+
```php
98+
use Closure;
99+
use Psr\Http\Message\ResponseInterface;
100+
use Psr\Http\Server\MiddlewareInterface;
101+
use Psr\Http\Server\RequestHandlerInterface;
102+
use Psr\Http\Message\ServerRequestInterface;
103+
use TheWebSolver\Codegarage\Lib\PipelineBridge;
104+
105+
class RequestHandler implements RequestHandlerInterface {
106+
/** @var array<Closure|MiddlewareInterface> */
107+
protected array $middlewares;
108+
109+
public function addMiddleware(Closure|MiddlewareInterface $middleware) {
110+
$this->middlewares[] = PipelineBridge::middlewareToPipe($middleware);
111+
}
112+
113+
public function handle( ServerRequestInterface $request ): ResponseInterface {
114+
// Concrete that implements "ResponseInterface".
115+
$response = new Response();
116+
117+
// Middleware that uses previous response as required.
118+
$middleware = function(
119+
ServerRequestInterface $request,
120+
RequestHandlerInterface $handler
121+
) {
122+
$previousResponse = $request->getAttribute(PipelineBridge::MIDDLEWARE_RESPONSE);
123+
124+
return '/app/route/' !== $request->getRequestTarget()
125+
? new Response(status: 404)
126+
: $previousResponse->withStatus(code: 200);
127+
}
128+
129+
$middlewares = array(
130+
...$this->middlewares,
131+
PipelineBridge::middlewareToPipe($middleware)
132+
);
133+
134+
return (new Pipeline())
135+
->use($request, $this) // Passed to "MiddlewareInterface::process()" method.
136+
->send(subject: $response)
137+
->through(pipes: $middlewares)
138+
->thenReturn();
139+
}
140+
}
141+
```

0 commit comments

Comments
 (0)