Skip to content

Commit 5883945

Browse files
committed
Added callback middleware
1 parent 27e4f97 commit 5883945

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

src/Middleware/CallbackMiddleware.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace DMT\Http\Client\Middleware;
4+
5+
use DMT\Http\Client\MiddlewareInterface;
6+
use DMT\Http\Client\RequestHandlerInterface;
7+
use Psr\Http\Client\ClientExceptionInterface;
8+
use Psr\Http\Message\RequestInterface;
9+
use Psr\Http\Message\ResponseInterface;
10+
11+
/**
12+
* Class CallbackMiddleware
13+
*
14+
* Callback middleware enables you to reuse other psr-7 compliant middleware that are applied to request or responses,
15+
* or use a closure to enable some functionalities which does not need a completely custom written middleware.
16+
*/
17+
class CallbackMiddleware implements MiddlewareInterface
18+
{
19+
public const TYPE_REQUEST = 1;
20+
public const TYPE_RESPONSE = 2;
21+
22+
/** @var callable */
23+
private $callback;
24+
private int $messageType;
25+
26+
/**
27+
* @param callable $callback A callback function to execute.
28+
* - in case of a request callback the callback receives a RequestInterface, and it must return also
29+
* - in case of a response callback it receives a ResponseInterface, which type it should return too
30+
* It is possible to apply a callback on both request and response, in these cases ensure the same type is returned
31+
* as the one that was received.
32+
* @param int $messageType The message type to apply the callback on
33+
*/
34+
public function __construct(callable $callback, int $messageType = self::TYPE_REQUEST)
35+
{
36+
$this->callback = $callback;
37+
$this->messageType = $messageType;
38+
}
39+
40+
/**
41+
* Execute the callback.
42+
*
43+
* @param RequestInterface $request
44+
* @param RequestHandlerInterface $handler
45+
* @return ResponseInterface
46+
* @throws ClientExceptionInterface
47+
*/
48+
public function process(RequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
49+
{
50+
if ($this->messageType & self::TYPE_REQUEST) {
51+
$request = call_user_func($this->callback, $request);
52+
}
53+
54+
$response = $handler->handle($request);
55+
56+
if ($this->messageType & self::TYPE_RESPONSE) {
57+
$response = call_user_func($this->callback, $response);
58+
}
59+
60+
return $response;
61+
}
62+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
namespace DMT\Test\Http\Client\Middleware;
4+
5+
use DMT\Http\Client\Middleware\CallbackMiddleware;
6+
use DMT\Http\Client\RequestHandler;
7+
use GuzzleHttp\Client;
8+
use GuzzleHttp\Handler\MockHandler;
9+
use GuzzleHttp\HandlerStack;
10+
use GuzzleHttp\Psr7\Request;
11+
use GuzzleHttp\Psr7\Response;
12+
use PHPUnit\Framework\TestCase;
13+
use Psr\Http\Message\RequestInterface;
14+
use Psr\Http\Message\ResponseInterface;
15+
16+
class CallbackMiddlewareTest extends TestCase
17+
{
18+
public function testRequestCallable()
19+
{
20+
$request = new Request('GET', '/');
21+
$client = new Client([
22+
'handler' => HandlerStack::create(
23+
new MockHandler([
24+
$response = new Response(200),
25+
])
26+
)
27+
]);
28+
29+
$isCalled = false;
30+
$callback = function (RequestInterface $request) use (&$isCalled) {
31+
$isCalled = true;
32+
return $request;
33+
};
34+
35+
$handler = new RequestHandler($client, new CallbackMiddleware($callback));
36+
37+
$this->assertSame($response, $handler->handle($request));
38+
$this->assertTrue($isCalled);
39+
}
40+
41+
public function testResponseCallable()
42+
{
43+
$request = new Request('GET', '/');
44+
$client = new Client([
45+
'handler' => HandlerStack::create(
46+
new MockHandler([
47+
$response = new Response(200),
48+
])
49+
)
50+
]);
51+
52+
$isCalled = false;
53+
$callback = function (ResponseInterface $response) use (&$isCalled) {
54+
$isCalled = true;
55+
return $response;
56+
};
57+
58+
$handler = new RequestHandler($client, new CallbackMiddleware($callback, CallbackMiddleware::TYPE_RESPONSE));
59+
60+
$this->assertSame($response, $handler->handle($request));
61+
$this->assertTrue($isCalled);
62+
}
63+
64+
public function testRequestAndResponseCallable()
65+
{
66+
$request = new Request('GET', '/');
67+
$client = new Client([
68+
'handler' => HandlerStack::create(
69+
new MockHandler([
70+
$response = new Response(200),
71+
])
72+
)
73+
]);
74+
75+
$count = 0;
76+
$callback = function ($requestOrResponse) use (&$count) {
77+
$count++;
78+
return $requestOrResponse;
79+
};
80+
81+
$handler = new RequestHandler(
82+
$client,
83+
new CallbackMiddleware(
84+
$callback,
85+
CallbackMiddleware::TYPE_REQUEST ^ CallbackMiddleware::TYPE_RESPONSE
86+
)
87+
);
88+
89+
$this->assertSame($response, $handler->handle($request));
90+
$this->assertSame(2, $count);
91+
}
92+
}

0 commit comments

Comments
 (0)