Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a simple way to negotiate request and response bodies (#253)
* Minor refactorings, working to add ability to grab parsed response body from integration tests * Refactored ResponseAssertions to take in a content negotiator so that any custom content negotiation logic the dev may have written is used in integration tests * Added interface for body negotiation that can be reused for controller param resolution and integration test response body resolution * Refactored controller param resolution to use IBodyNegotiator instead of IContentNegotiator for DRY * Updated CHANGELOG * Updated integration test class to expose methods for negotiating request and response bodies
- Loading branch information
1 parent
8968490
commit a259240
Showing
17 changed files
with
516 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
/** | ||
* Aphiria | ||
* | ||
* @link https://www.aphiria.com | ||
* @copyright Copyright (C) 2023 David Young | ||
* @license https://github.com/aphiria/aphiria/blob/1.x/LICENSE.md | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Aphiria\ContentNegotiation; | ||
|
||
use Aphiria\Net\Http\IRequest; | ||
use Aphiria\Net\Http\IResponse; | ||
|
||
/** | ||
* Defines a body negotiator | ||
*/ | ||
final class BodyNegotiator implements IBodyNegotiator | ||
{ | ||
/** | ||
* @param IContentNegotiator $contentNegotiator The content negotiator to use when negotiating message bodies | ||
*/ | ||
public function __construct(private readonly IContentNegotiator $contentNegotiator = new ContentNegotiator()) | ||
{ | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function negotiateRequestBody(string $type, IRequest $request): float|object|int|bool|array|string|null | ||
{ | ||
if (($body = $request->getBody()) === null) { | ||
return null; | ||
} | ||
|
||
$contentNegotiationResult = $this->contentNegotiator->negotiateRequestContent($type, $request); | ||
$mediaTypeFormatter = $contentNegotiationResult->formatter; | ||
|
||
if ($mediaTypeFormatter === null) { | ||
throw new FailedContentNegotiationException("No media type formatter available for $type"); | ||
} | ||
|
||
return $mediaTypeFormatter->readFromStream($body->readAsStream(), $type); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function negotiateResponseBody(string $type, IRequest $request, IResponse $response): float|object|int|bool|array|string|null | ||
{ | ||
if (($body = $response->getBody()) === null) { | ||
return null; | ||
} | ||
|
||
$contentNegotiationResult = $this->contentNegotiator->negotiateResponseContent($type, $request); | ||
$mediaTypeFormatter = $contentNegotiationResult->formatter; | ||
|
||
if ($mediaTypeFormatter === null) { | ||
throw new FailedContentNegotiationException("No media type formatter available for $type"); | ||
} | ||
|
||
return $mediaTypeFormatter->readFromStream($body->readAsStream(), $type); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/ContentNegotiation/src/FailedContentNegotiationException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
/** | ||
* Aphiria | ||
* | ||
* @link https://www.aphiria.com | ||
* @copyright Copyright (C) 2023 David Young | ||
* @license https://github.com/aphiria/aphiria/blob/1.x/LICENSE.md | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Aphiria\ContentNegotiation; | ||
|
||
use Exception; | ||
|
||
/** | ||
* Defines the exception that is thrown when content negotiation fails | ||
*/ | ||
class FailedContentNegotiationException extends Exception | ||
{ | ||
} |
Oops, something went wrong.