Skip to content

Commit

Permalink
Updated with the final name for the standard: RF7807
Browse files Browse the repository at this point in the history
  • Loading branch information
Nil Portugues Caldero committed Jun 3, 2016
1 parent 06c4d8c commit be04699
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 18 deletions.
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,29 @@ PSR7 Response implementation for the [Problem Details for HTTP APIs (RFC7807)](h

To report a single error, all you need to do is pass in the mandatory parameters and you'll be fine.

**Using the constructor**
**Straightforward usage (recommended)**

This is probably the fastest way and it's really convenient as it hides the presenter and creating the instances from you.

```php
<?php
use NilPortugues\Api\Problem\ApiProblemResponse;

$additionalDetails = []; //you may pass additional details too.

ApiProblemResponse::json(404,'User with id 5 not found.', 'Not Found', 'user.not_found', $additionalDetails);
ApiProblemResponse::xml(404,'User with id 5 not found.', 'Not Found', 'user.not_found', $additionalDetails);

ApiProblemResponse::fromExceptionToJson($exception);
ApiProblemResponse::fromExceptionToXml($exception);
```

**Using the constructor and handling the response yourself.**

```php
use NilPortugues\Api\Problem\ApiProblem;
use NilPortugues\Api\Problem\ApiProblemResponse;
use NilPortugues\Api\Problem\Presenter\JsonPresenter;

$apiProblem = new ApiProblem(
404,
'User with id 5 not found.',
Expand All @@ -28,10 +47,13 @@ $presenter = new JsonPresenter($apiProblem); //or XmlPresenter
return new ApiProblemResponse($presenter);
```

**Using an Exception**
**Using an Exception and handling the response yourself.**

```php
<?php
use NilPortugues\Api\Problem\ApiProblem;
use NilPortugues\Api\Problem\ApiProblemResponse;
use NilPortugues\Api\Problem\Presenter\JsonPresenter;

try {
//...your code throwing an exception
throw new \Exception('User with id 5 not found.', 404);
Expand All @@ -49,7 +71,10 @@ try {
In order to report more than problem, you must use the additional details parameter.

```php
<?php
use NilPortugues\Api\Problem\ApiProblem;
use NilPortugues\Api\Problem\ApiProblemResponse;
use NilPortugues\Api\Problem\Presenter\JsonPresenter;

try {
// some code of yours throws an exception... for instance:
throw new \Exception('User data is not valid.', 500);
Expand Down Expand Up @@ -116,7 +141,7 @@ Content-Type: application/problem+xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:XXXX">
<problem xmlns="urn:ietf:rfc:7807">
<title>Input values do not match the requirements</title>
<status>500</status>
<detail>User data is not valid.</detail>
Expand Down
11 changes: 6 additions & 5 deletions src/ApiProblem/ApiProblem.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace NilPortugues\Api\Problem;

use Exception;
use NilPortugues\Assert\Assert;

/**
Expand Down Expand Up @@ -117,14 +118,14 @@ public function __construct($status, $detail, $title = '', $type = '', array $ad
}

/**
* @param \Exception $exception
* @param string $title
* @param string $type
* @param array $additionalDetails
* @param Exception $exception
* @param string $title
* @param string $type
* @param array $additionalDetails
*
* @return ApiProblem
*/
public static function fromException(\Exception $exception, $title = '', $type = '', array $additionalDetails = [])
public static function fromException(Exception $exception, $title = '', $type = '', array $additionalDetails = [])
{
$eCode = $exception->getCode();
$code = (isset($eCode) && is_int($eCode)) ? $eCode : 500;
Expand Down
68 changes: 65 additions & 3 deletions src/ApiProblem/ApiProblemResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

namespace NilPortugues\Api\Problem;

use Exception;
use GuzzleHttp\Psr7\Response;
use NilPortugues\Api\Problem\Presenter\JsonPresenter;
use NilPortugues\Api\Problem\Presenter\Presenter;
use NilPortugues\Api\Problem\Presenter\XmlPresenter;

/**
* Class ApiProblemResponse.
*/
class ApiProblemResponse extends Response
{
/**
Expand All @@ -41,4 +41,66 @@ protected function responseHeader(Presenter $presenter)
{
return ($presenter->format() === 'xml') ? 'application/problem+xml' : 'application/problem+json';
}

/**
* @param $status
* @param $detail
* @param string $title
* @param string $type
* @param array $additionalDetails
*
* @return ApiProblemResponse
*/
public static function json($status, $detail, $title = '', $type = '', array $additionalDetails = [])
{
return new self(new JsonPresenter(new ApiProblem($status, $detail, $title, $type, $additionalDetails)));
}

/**
* @param Exception $exception
* @param string $title
* @param string $type
* @param array $additionalDetails
*
* @return ApiProblemResponse
*/
public static function fromExceptionToJson(
Exception $exception,
$title = '',
$type = '',
array $additionalDetails = []
) {
return new self(new JsonPresenter(ApiProblem::fromException($exception, $title, $type, $additionalDetails)));
}

/**
* @param $status
* @param $detail
* @param string $title
* @param string $type
* @param array $additionalDetails
*
* @return ApiProblemResponse
*/
public static function xml($status, $detail, $title = '', $type = '', array $additionalDetails = [])
{
return new self(new XmlPresenter(new ApiProblem($status, $detail, $title, $type, $additionalDetails)));
}

/**
* @param Exception $exception
* @param string $title
* @param string $type
* @param array $additionalDetails
*
* @return ApiProblemResponse
*/
public static function fromExceptionToXml(
Exception $exception,
$title = '',
$type = '',
array $additionalDetails = []
) {
return new self(new XmlPresenter(ApiProblem::fromException($exception, $title, $type, $additionalDetails)));
}
}
2 changes: 1 addition & 1 deletion src/ApiProblem/Presenter/XmlPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function contents()

return <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:XXXX">
<problem xmlns="urn:ietf:rfc:7807">
$flattenedLines
</problem>
XML;
Expand Down
76 changes: 75 additions & 1 deletion tests/ApiProblem/ApiProblemResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,81 @@ public function testItWillCreateXmlResponse()

$body = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:XXXX">
<problem xmlns="urn:ietf:rfc:7807">
<title>Not Found</title>
<status>404</status>
<detail>User with id 5 not found.</detail>
<type>http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html</type>
</problem>
XML;

$this->assertEquals($response->getBody()->getContents(), $body);
$this->assertEquals($response->getStatusCode(), 404);
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+xml');
}

public function testToJson()
{
$response = ApiProblemResponse::json(404, 'User with id 5 not found.', 'Not Found');

$body = <<<JSON
{
"title": "Not Found",
"status": 404,
"detail": "User with id 5 not found."
}
JSON;

$this->assertEquals($response->getBody()->getContents(), $body);
$this->assertEquals($response->getStatusCode(), 404);
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+json');
}

public function testToJsonFromException()
{
$exception = new \Exception('User with id 5 not found.', 404);
$response = ApiProblemResponse::fromExceptionToJson($exception);

$body = <<<JSON
{
"title": "Not Found",
"status": 404,
"detail": "User with id 5 not found.",
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"
}
JSON;

$this->assertEquals($response->getBody()->getContents(), $body);
$this->assertEquals($response->getStatusCode(), 404);
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+json');
}

public function testToXml()
{
$response = ApiProblemResponse::xml(404, 'User with id 5 not found.', 'Not Found');

$body = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:7807">
<title>Not Found</title>
<status>404</status>
<detail>User with id 5 not found.</detail>
</problem>
XML;

$this->assertEquals($response->getBody()->getContents(), $body);
$this->assertEquals($response->getStatusCode(), 404);
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+xml');
}

public function testToXmlFromException()
{
$exception = new \Exception('User with id 5 not found.', 404);
$response = ApiProblemResponse::fromExceptionToXml($exception);

$body = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:7807">
<title>Not Found</title>
<status>404</status>
<detail>User with id 5 not found.</detail>
Expand Down
4 changes: 2 additions & 2 deletions tests/ApiProblem/Presenter/XmlPresenterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function testItCanWriteXmlFromNestedArray()
{
$expected = <<<JSON
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:XXXX">
<problem xmlns="urn:ietf:rfc:7807">
<title>Input values do not match the requirements</title>
<status>500</status>
<detail>User data is not valid.</detail>
Expand All @@ -56,7 +56,7 @@ public function testItCanCastObjectToString()
{
$expected = <<<JSON
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:XXXX">
<problem xmlns="urn:ietf:rfc:7807">
<title>Input values do not match the requirements</title>
<status>500</status>
<detail>User data is not valid.</detail>
Expand Down

0 comments on commit be04699

Please sign in to comment.