Skip to content

Commit 89b1453

Browse files
committed
Merge pull request #6 from rstgroup/feature/request-id-provider
Feature/request id provider
2 parents 8d53690 + ff8114f commit 89b1453

13 files changed

+382
-242
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
/vendor/
22
composer.lock
3-
tmp/
3+
tmp/
4+
phpunit-coverage-clover.xml
5+
.idea
6+

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,30 @@ This middleware provide framework-agnostic possibility to generate and add to re
1414
```json
1515
{
1616
"require": {
17-
"php-middleware/request-id": "^2.0.0"
17+
"php-middleware/request-id": "^3.0.0"
1818
}
1919
}
2020
```
2121

2222
## Usage
2323

24-
This middleware require in contructor `PhpMiddleware\RequestId\Generator\GeneratorInterface` implementation.
24+
This middleware require in contructor `PhpMiddleware\RequestId\RequestIdProviderFactoryInterface` implementation which
25+
must create a new `RequestIdProviderInterface` object. We provide `RequestIdProvider` default implementation.
2526

2627
```php
27-
$requestIdMiddleware = new PhpMiddleware\LogHttpMessages\RequestIdMiddleware($generator);
28+
$generator = new PhpMiddleware\RequestId\Generator\PhpUniqidGenerator();
29+
$requestIdProvider = new PhpMiddleware\RequestId\RequestIdProviderFactory($generator);
30+
$requestIdMiddleware = new PhpMiddleware\LogHttpMessages\RequestIdMiddleware($requestIdProvider);
2831

2932
$app = new MiddlewareRunner();
3033
$app->add($requestIdMiddleware);
3134
$app->run($request, $response);
3235
```
3336

34-
All middleware constructor options:
37+
All Provider factory constructor options:
3538

3639
* `PhpMiddleware\RequestId\Generator\GeneratorInterface` `$generator` - generator implementation (required)
3740
* `bool|PhpMiddleware\RequestId\OverridePolicy\OverridePolicyInterface` `$allowOverride` (default `true`) - if `true` and request id header exists in incoming request, then value from request header will be used in middleware, using generator will be avoid
38-
* `string` `$responseHeader` (default `X-Request-Id`) - request id will be added to response as header with given name. If it's not string request id will be not added to response
3941
* `string` `$requestHeader` (default `X-Request-Id`) - request header name
4042

4143
How to get request id in my application?

src/Exception/InvalidRequestId.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace PhpMiddleware\RequestId\Exception;
44

5-
class InvalidRequestId extends \UnexpectedValueException
6-
{
5+
use UnexpectedValueException;
76

7+
class InvalidRequestId extends UnexpectedValueException implements RequestIdExceptionInterface
8+
{
89
}

src/Exception/MissingRequestId.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace PhpMiddleware\RequestId\Exception;
44

5-
class MissingRequestId extends \UnexpectedValueException
6-
{
5+
use UnexpectedValueException;
76

7+
class MissingRequestId extends UnexpectedValueException implements RequestIdExceptionInterface
8+
{
89
}

src/Exception/NotGenerated.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44

55
class NotGenerated extends MissingRequestId
66
{
7-
87
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace PhpMiddleware\RequestId\Exception;
4+
5+
interface RequestIdExceptionInterface
6+
{
7+
}

src/RequestIdMiddleware.php

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,20 @@
22

33
namespace PhpMiddleware\RequestId;
44

5-
use PhpMiddleware\RequestId\Exception\InvalidRequestId;
6-
use PhpMiddleware\RequestId\Exception\MissingRequestId;
75
use PhpMiddleware\RequestId\Exception\NotGenerated;
8-
use PhpMiddleware\RequestId\Generator\GeneratorInterface;
9-
use PhpMiddleware\RequestId\OverridePolicy\OverridePolicyInterface;
10-
use PhpMiddleware\RequestId\RequestIdProviderInterface;
6+
use PhpMiddleware\RequestId\RequestIdProviderFactoryInterface as RequestIdProviderFactory;
117
use Psr\Http\Message\ResponseInterface;
128
use Psr\Http\Message\ServerRequestInterface;
139

14-
class RequestIdMiddleware implements RequestIdProviderInterface
10+
final class RequestIdMiddleware implements RequestIdProviderInterface
1511
{
16-
const DEFAULT_HEADER_REQUEST_ID = 'X-Request-Id';
12+
const DEFAULT_RESPONSE_HEADER = 'X-Request-Id';
1713
const ATTRIBUTE_NAME = 'request-id';
1814

1915
/**
20-
* @var GeneratorInterface
16+
* @var RequestIdProviderFactory
2117
*/
22-
protected $generator;
23-
24-
/**
25-
* @var bool|OverridePolicyInterface
26-
*/
27-
protected $allowOverride;
18+
protected $requestIdProviderFactory;
2819

2920
/**
3021
* @var mixed
@@ -37,27 +28,15 @@ class RequestIdMiddleware implements RequestIdProviderInterface
3728
protected $responseHeader;
3829

3930
/**
40-
*
41-
* @var string
42-
*/
43-
protected $requestHeader;
44-
45-
/**
46-
* @param GeneratorInterface $generator
47-
* @param bool|OverridePolicyInterface $allowOverride
31+
* @param RequestIdProviderFactory $requestIdProviderFactory
4832
* @param string $responseHeader
49-
* @param string $requestHeader
5033
*/
5134
public function __construct(
52-
GeneratorInterface $generator,
53-
$allowOverride = true,
54-
$responseHeader = self::DEFAULT_HEADER_REQUEST_ID,
55-
$requestHeader = self::DEFAULT_HEADER_REQUEST_ID
35+
RequestIdProviderFactory $requestIdProviderFactory,
36+
$responseHeader = self::DEFAULT_RESPONSE_HEADER
5637
) {
57-
$this->generator = $generator;
58-
$this->allowOverride = $allowOverride;
38+
$this->requestIdProviderFactory = $requestIdProviderFactory;
5939
$this->responseHeader = $responseHeader;
60-
$this->requestHeader = $requestHeader;
6140
}
6241

6342
/**
@@ -69,7 +48,10 @@ public function __construct(
6948
*/
7049
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
7150
{
72-
$this->requestId = $this->getRequestIdFromRequest($request);
51+
$requestIdProvider = $this->requestIdProviderFactory->create($request);
52+
53+
$this->requestId = $requestIdProvider->getRequestId();
54+
7355
$requestWithAttribute = $request->withAttribute(self::ATTRIBUTE_NAME, $this->requestId);
7456

7557
$nextResponse = $next($requestWithAttribute, $response);
@@ -92,49 +74,4 @@ public function getRequestId()
9274
}
9375
return $this->requestId;
9476
}
95-
96-
/**
97-
* @param ServerRequestInterface $request
98-
*
99-
* @return mixed
100-
*
101-
* @throws MissingRequestId
102-
* @throws NotGenerated
103-
*/
104-
protected function getRequestIdFromRequest(ServerRequestInterface $request)
105-
{
106-
if ($this->isPossibleToGetFromRequest($request)) {
107-
$requestId = $request->getHeaderLine($this->requestHeader);
108-
109-
if (empty($requestId)) {
110-
throw new MissingRequestId(sprintf('Missing request id in "%s" request header', $this->requestHeader));
111-
}
112-
} else {
113-
$requestId = $this->generator->generateRequestId();
114-
115-
if (empty($requestId)) {
116-
throw new InvalidRequestId('Generator return empty value');
117-
}
118-
if (!is_string($requestId)) {
119-
throw new InvalidRequestId('Request id is not a string');
120-
}
121-
}
122-
return $requestId;
123-
}
124-
125-
/**
126-
* @param ServerRequestInterface $request
127-
*
128-
* @return bool
129-
*/
130-
protected function isPossibleToGetFromRequest(ServerRequestInterface $request)
131-
{
132-
if ($this->allowOverride instanceof OverridePolicyInterface) {
133-
$allowOverride = $this->allowOverride->isAllowToOverride($request);
134-
} else {
135-
$allowOverride = $this->allowOverride;
136-
}
137-
138-
return $allowOverride === true && $request->hasHeader($this->requestHeader);
139-
}
14077
}

src/RequestIdProvider.php

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
namespace PhpMiddleware\RequestId;
3+
4+
use PhpMiddleware\RequestId\Exception\InvalidRequestId;
5+
use PhpMiddleware\RequestId\Exception\MissingRequestId;
6+
use PhpMiddleware\RequestId\Generator\GeneratorInterface;
7+
use PhpMiddleware\RequestId\OverridePolicy\OverridePolicyInterface;
8+
use Psr\Http\Message\ServerRequestInterface;
9+
10+
final class RequestIdProvider implements RequestIdProviderInterface
11+
{
12+
const DEFAULT_REQUEST_HEADER = 'X-Request-Id';
13+
14+
/**
15+
* @var ServerRequestInterface
16+
*/
17+
protected $request;
18+
19+
/**
20+
* @var GeneratorInterface
21+
*/
22+
protected $generator;
23+
24+
/**
25+
* @var bool|OverridePolicyInterface
26+
*/
27+
protected $allowOverride;
28+
29+
/**
30+
* @var mixed
31+
*/
32+
protected $requestId;
33+
34+
/**
35+
*
36+
* @var string
37+
*/
38+
protected $requestHeader;
39+
40+
/**
41+
* @param ServerRequestInterface $request
42+
* @param GeneratorInterface $generator
43+
* @param bool|OverridePolicyInterface $allowOverride
44+
* @param string $requestHeader
45+
*/
46+
public function __construct(
47+
ServerRequestInterface $request,
48+
GeneratorInterface $generator,
49+
$allowOverride = true,
50+
$requestHeader = self::DEFAULT_REQUEST_HEADER
51+
)
52+
{
53+
$this->request = $request;
54+
$this->generator = $generator;
55+
$this->allowOverride = $allowOverride;
56+
$this->requestHeader = $requestHeader;
57+
}
58+
59+
/**
60+
* @return mixed
61+
*
62+
* @throws RequestIdExceptionInterface
63+
*/
64+
public function getRequestId()
65+
{
66+
if ($this->requestId !== null) {
67+
return $this->requestId;
68+
}
69+
70+
if ($this->isPossibleToGetFromRequest($this->request)) {
71+
$requestId = $this->request->getHeaderLine($this->requestHeader);
72+
73+
if (empty($requestId)) {
74+
throw new MissingRequestId(sprintf('Missing request id in "%s" request header', $this->requestHeader));
75+
}
76+
} else {
77+
$requestId = $this->generator->generateRequestId();
78+
79+
if (empty($requestId)) {
80+
throw new InvalidRequestId('Generator return empty value');
81+
}
82+
if (!is_string($requestId)) {
83+
throw new InvalidRequestId('Request id is not a string');
84+
}
85+
}
86+
$this->requestId = $requestId;
87+
88+
return $requestId;
89+
}
90+
91+
/**
92+
* @param ServerRequestInterface $request
93+
*
94+
* @return bool
95+
*/
96+
protected function isPossibleToGetFromRequest(ServerRequestInterface $request)
97+
{
98+
if ($this->allowOverride instanceof OverridePolicyInterface) {
99+
$allowOverride = $this->allowOverride->isAllowToOverride($request);
100+
} else {
101+
$allowOverride = $this->allowOverride;
102+
}
103+
104+
return $allowOverride === true && $request->hasHeader($this->requestHeader);
105+
}
106+
}

src/RequestIdProviderFactory.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace PhpMiddleware\RequestId;
4+
5+
use PhpMiddleware\RequestId\Generator\GeneratorInterface;
6+
use PhpMiddleware\RequestId\OverridePolicy\OverridePolicyInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
9+
/**
10+
* @codeCoverageIgnore
11+
*/
12+
final class RequestIdProviderFactory implements RequestIdProviderFactoryInterface
13+
{
14+
/**
15+
* @var GeneratorInterface
16+
*/
17+
protected $generator;
18+
19+
/**
20+
* @var bool|OverridePolicyInterface
21+
*/
22+
protected $allowOverride;
23+
24+
/**
25+
* @var string
26+
*/
27+
protected $requestHeader;
28+
29+
/**
30+
* @param GeneratorInterface $generator
31+
* @param bool|OverridePolicyInterface $allowOverride
32+
* @param string $requestHeader
33+
*/
34+
public function __construct(
35+
GeneratorInterface $generator,
36+
$allowOverride = true,
37+
$requestHeader = RequestIdProvider::DEFAULT_REQUEST_HEADER
38+
) {
39+
$this->generator = $generator;
40+
$this->allowOverride = $allowOverride;
41+
$this->requestHeader = $requestHeader;
42+
}
43+
44+
/**
45+
* @param ServerRequestInterface $request
46+
* @return RequestIdProvider
47+
*/
48+
public function create(ServerRequestInterface $request)
49+
{
50+
return new RequestIdProvider($request, $this->generator, $this->allowOverride, $this->requestHeader);
51+
}
52+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace PhpMiddleware\RequestId;
4+
5+
use Psr\Http\Message\ServerRequestInterface;
6+
7+
interface RequestIdProviderFactoryInterface
8+
{
9+
/**
10+
* @param ServerRequestInterface $request
11+
* @return RequestIdProvider
12+
*/
13+
public function create(ServerRequestInterface $request);
14+
}

0 commit comments

Comments
 (0)