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

Commit

Permalink
Merge pull request #3 from jakejohns/feature/json-decoder
Browse files Browse the repository at this point in the history
Add JsonDecoder middleware
  • Loading branch information
Paul M. Jones committed Jul 23, 2015
2 parents 9383059 + d337973 commit 952cdce
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The _ResponseSender_ does nothing with the `$request` or `$response`, passing th

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.

To add the _ResponseSender_ to your Real queue, instantiate it directly ...
To add the _ResponseSender_ to your Relay queue, instantiate it directly ...

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

... or use a `$resolver` of your choice to instantiate it from the `$queue`.

## JsonDecoder

Again, the _JsonDecoder_ does what it sounds like: it deserializes the JSON
payload of a PSR-7 request object and makes the parameters available in
subsequent middleware decorators.

The _JsonDecoder_ checks the incoming request for a method other than `GET` and
for an `application/json` `Content-Type` header. If it finds both of these, it
decodes the JSON and makes it available as the _parsed body_ of the `$request`
before passing it and the `$response` to `$next`. If the method is `GET` or the
`Content-Type` header does not specify `application/json`, the _JsonDecoder_
does nothing with the `$request` and passes it and the `$response` to `$next`.


To add the _JsonDecoder_ to your queue, instantiate it directly...

```php
$queue = new \Relay\Middleware\JsonDecoder();
```

... or use a `$resolver` of your choice to instantiate it from the `$queue`.

To access the decoded parameters in subsequent middleware, use the
`getParsedBody()` method of the `$request`

```php
$decodedJsonData = $request->getParsedBody();
```
24 changes: 24 additions & 0 deletions src/JsonDecoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace Relay\Middleware;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class JsonDecoder
{
public function __invoke(Request $request, Response $response, callable $next)
{
$type = $request->getHeader('Content-Type');
$method = $request->getMethod();

if ('GET' != $method
&& ! empty($type)
&& 'application/json' == strtolower($type[0])
) {
$body = (string) $request->getBody();
$request = $request->withParsedBody(json_decode($body));
}

return $next($request, $response);
}
}
62 changes: 62 additions & 0 deletions tests/JsonDecoderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
namespace Relay\Middleware;

use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
use Zend\Diactoros\Stream;


class JsonDecoderTest extends \PHPUnit_Framework_TestCase
{

protected $data = ['foo', 'bar'];


public function requestProvider()
{
return [
['GET' , 'application/json', []],
['GET' , null, []],
['POST' , 'application/json', $this->data],
['POST' , null, []],
['PUT' , 'application/json', $this->data],
['PUT' , null, []],
['PATCH' , 'application/json', $this->data],
['PATCH' , null, []],
['other' , 'application/json', $this->data],
['other' , null, []]
];
}

/**
* @dataProvider requestProvider
*/
public function testParser($method, $contentType, $expected)
{
$json = json_encode($this->data);

$stream = new Stream('php://temp', 'wb+');
$stream->write($json);

$jsonDecoder = new JsonDecoder();

$response = new Response();
$request = ServerRequestFactory::fromGlobals()
->withMethod($method)
->withBody($stream);

if ($contentType) {
$request = $request->withHeader('Content-Type', $contentType);
}

$parsedRequest = $jsonDecoder(
$request,
$response,
function ($request, $response) {
return $request;
}
);

$this->assertEquals($expected, $parsedRequest->getParsedBody());
}
}

0 comments on commit 952cdce

Please sign in to comment.