Skip to content
This repository was archived by the owner on Mar 5, 2020. It is now read-only.

Commit 952cdce

Browse files
author
Paul M. Jones
committed
Merge pull request #3 from jakejohns/feature/json-decoder
Add JsonDecoder middleware
2 parents 9383059 + d337973 commit 952cdce

3 files changed

Lines changed: 116 additions & 1 deletion

File tree

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The _ResponseSender_ does nothing with the `$request` or `$response`, passing th
1515

1616
The _ResponseSender_ is intended to go at the top of the Relay queue, so that it is the middleware with the last opportunity to do something with the returned response.
1717

18-
To add the _ResponseSender_ to your Real queue, instantiate it directly ...
18+
To add the _ResponseSender_ to your Relay queue, instantiate it directly ...
1919

2020
```php
2121
$queue[] = new \Relay\Middleware\ResponseSender();
@@ -38,3 +38,32 @@ $queue = new \Relay\Middleware\ExceptionHandler(new ResponseImplementation());
3838
```
3939

4040
... or use a `$resolver` of your choice to instantiate it from the `$queue`.
41+
42+
## JsonDecoder
43+
44+
Again, the _JsonDecoder_ does what it sounds like: it deserializes the JSON
45+
payload of a PSR-7 request object and makes the parameters available in
46+
subsequent middleware decorators.
47+
48+
The _JsonDecoder_ checks the incoming request for a method other than `GET` and
49+
for an `application/json` `Content-Type` header. If it finds both of these, it
50+
decodes the JSON and makes it available as the _parsed body_ of the `$request`
51+
before passing it and the `$response` to `$next`. If the method is `GET` or the
52+
`Content-Type` header does not specify `application/json`, the _JsonDecoder_
53+
does nothing with the `$request` and passes it and the `$response` to `$next`.
54+
55+
56+
To add the _JsonDecoder_ to your queue, instantiate it directly...
57+
58+
```php
59+
$queue = new \Relay\Middleware\JsonDecoder();
60+
```
61+
62+
... or use a `$resolver` of your choice to instantiate it from the `$queue`.
63+
64+
To access the decoded parameters in subsequent middleware, use the
65+
`getParsedBody()` method of the `$request`
66+
67+
```php
68+
$decodedJsonData = $request->getParsedBody();
69+
```

src/JsonDecoder.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
namespace Relay\Middleware;
3+
4+
use Psr\Http\Message\ResponseInterface as Response;
5+
use Psr\Http\Message\ServerRequestInterface as Request;
6+
7+
class JsonDecoder
8+
{
9+
public function __invoke(Request $request, Response $response, callable $next)
10+
{
11+
$type = $request->getHeader('Content-Type');
12+
$method = $request->getMethod();
13+
14+
if ('GET' != $method
15+
&& ! empty($type)
16+
&& 'application/json' == strtolower($type[0])
17+
) {
18+
$body = (string) $request->getBody();
19+
$request = $request->withParsedBody(json_decode($body));
20+
}
21+
22+
return $next($request, $response);
23+
}
24+
}

tests/JsonDecoderTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
namespace Relay\Middleware;
3+
4+
use Zend\Diactoros\Response;
5+
use Zend\Diactoros\ServerRequestFactory;
6+
use Zend\Diactoros\Stream;
7+
8+
9+
class JsonDecoderTest extends \PHPUnit_Framework_TestCase
10+
{
11+
12+
protected $data = ['foo', 'bar'];
13+
14+
15+
public function requestProvider()
16+
{
17+
return [
18+
['GET' , 'application/json', []],
19+
['GET' , null, []],
20+
['POST' , 'application/json', $this->data],
21+
['POST' , null, []],
22+
['PUT' , 'application/json', $this->data],
23+
['PUT' , null, []],
24+
['PATCH' , 'application/json', $this->data],
25+
['PATCH' , null, []],
26+
['other' , 'application/json', $this->data],
27+
['other' , null, []]
28+
];
29+
}
30+
31+
/**
32+
* @dataProvider requestProvider
33+
*/
34+
public function testParser($method, $contentType, $expected)
35+
{
36+
$json = json_encode($this->data);
37+
38+
$stream = new Stream('php://temp', 'wb+');
39+
$stream->write($json);
40+
41+
$jsonDecoder = new JsonDecoder();
42+
43+
$response = new Response();
44+
$request = ServerRequestFactory::fromGlobals()
45+
->withMethod($method)
46+
->withBody($stream);
47+
48+
if ($contentType) {
49+
$request = $request->withHeader('Content-Type', $contentType);
50+
}
51+
52+
$parsedRequest = $jsonDecoder(
53+
$request,
54+
$response,
55+
function ($request, $response) {
56+
return $request;
57+
}
58+
);
59+
60+
$this->assertEquals($expected, $parsedRequest->getParsedBody());
61+
}
62+
}

0 commit comments

Comments
 (0)