-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Boom: rewritten ApiMiddlewares to more plug-in based conceptions, fin…
…alize content negotiation, added debugging view, synchronize URL matching (trailing slashes), added basic readme
- Loading branch information
Showing
31 changed files
with
931 additions
and
165 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# API - Guidelines | ||
|
||
## Content | ||
|
||
- [Installation - how to register an extension](#installation) | ||
|
||
## Installation | ||
|
||
Simpliest way to register this API is via [Nette\DI\CompilerExtension](https://api.nette.org/2.4/Nette.DI.CompilerExtension.html). | ||
|
||
```yaml | ||
extensions: | ||
api: Contributte\Api\Bridges\DI\ApiAnnotationsExtension | ||
``` | ||
|
||
This is complex example of API configuration with middleware support. | ||
|
||
```yaml | ||
extensions: | ||
api: Contributte\Api\Bridges\DI\ApiAnnotationsExtension | ||
middlewares: Contributte\Middlewares\DI\NetteMiddlewareExtension | ||
|
||
services: | ||
# Middlewares | ||
middleware.tracy: Contributte\Middlewares\Middleware\TracyMiddleware | ||
middleware.basepath: Contributte\Middlewares\Middleware\AutoBasePathMiddleware | ||
middleware.router: Contributte\Middlewares\Middleware\RouterMiddleware([ | ||
"^/api/{path:.+}": @middleware.api, | ||
"^/{path:.*}": @middleware.presenter | ||
]) | ||
|
||
# Case #1 (handle API request)[api/] | ||
middleware.api: | ||
class: Contributte\Api\Bridges\Middlewares\ApiDataMiddleware([ | ||
Contributte\Api\Bridges\Middlewares\ApiRouter("^/api/{api}{?format:\\.json|debug}"), | ||
Contributte\Api\Bridges\Middlewares\ApiContentNegotiation([ | ||
Contributte\Api\Bridges\Middlewares\Negotiation\UrlNegotiator([ | ||
"json": Contributte\Api\Bridges\Middlewares\Negotiation\Transformer\JsonTransformer(), | ||
"debug": Contributte\Api\Bridges\Tracy\Negotiation\Transformer\DebugTransformer(), | ||
"*": Contributte\Api\Bridges\Middlewares\Negotiation\Transformer\JsonTransformer() | ||
]) | ||
]), | ||
Contributte\Api\Bridges\Middlewares\ApiEmitter() | ||
]) | ||
|
||
# Case #2 (handle classic nette application) | ||
middleware.presenter: | ||
class: Contributte\Middlewares\Middleware\PresenterMiddleware | ||
setup: | ||
- setErrorPresenter(Error) | ||
- setCatchExceptions(FALSE) | ||
|
||
- {class: App\Middlewares\RootMiddleware, inject: true} | ||
|
||
middlewares: | ||
middlewares: | ||
- @middleware.tracy | ||
- @middleware.basepath | ||
- @middleware.router | ||
``` |
This file was deleted.
Oops, something went wrong.
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 was deleted.
Oops, something went wrong.
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,80 @@ | ||
<?php | ||
|
||
namespace Contributte\Api\Bridges\Middlewares; | ||
|
||
use Contributte\Api\Bridges\Middlewares\Negotiation\INegotiator; | ||
use Contributte\Api\Exception\Logical\InvalidStateException; | ||
use Contributte\Api\Http\Request\ApiRequest; | ||
use Contributte\Api\Http\Response\ApiDataResponse; | ||
use Contributte\Api\Http\Response\ApiResponse; | ||
|
||
class ApiContentNegotiation implements IInvoker | ||
{ | ||
|
||
/** @var INegotiator[] */ | ||
protected $negotiators = []; | ||
|
||
/** | ||
* @param INegotiator[] $negotiators | ||
*/ | ||
public function __construct(array $negotiators) | ||
{ | ||
$this->negotiators = $negotiators; | ||
} | ||
|
||
/** | ||
* API - INVOKING ********************************************************** | ||
*/ | ||
|
||
/** | ||
* @param ApiRequest $request | ||
* @param ApiResponse|ApiDataResponse $response | ||
* @param callable $next | ||
* @return ApiResponse | ||
*/ | ||
public function invoke(ApiRequest $request, ApiResponse $response, callable $next) | ||
{ | ||
// Pass to next invoker | ||
$response = $next($request, $response); | ||
|
||
// If the response is not a appropriate type of or | ||
// does not have a any data, return response immediately | ||
if (!($response instanceof ApiDataResponse) || | ||
!$response->isEmpty() | ||
) { | ||
return $response; | ||
} | ||
|
||
// Otherwise, pass to negotiator | ||
return $this->negotiate($request, $response); | ||
} | ||
|
||
/** | ||
* HELPERS ***************************************************************** | ||
*/ | ||
|
||
/** | ||
* @param ApiRequest $request | ||
* @param ApiResponse $response | ||
* @return ApiResponse | ||
*/ | ||
protected function negotiate(ApiRequest $request, ApiResponse $response) | ||
{ | ||
if (!$this->negotiators) { | ||
throw new InvalidStateException('Please add at least one negotiator'); | ||
} | ||
|
||
foreach ($this->negotiators as $negotiator) { | ||
// Pass to negotiator and check return value | ||
$negotiated = $negotiator->negotiate($request, $response); | ||
|
||
// If it's not NULL, we have an ApiResponse | ||
if ($negotiated !== NULL) { | ||
return $negotiated; | ||
} | ||
} | ||
|
||
return $response; | ||
} | ||
|
||
} |
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 | ||
|
||
namespace Contributte\Api\Bridges\Middlewares; | ||
|
||
use Contributte\Api\Http\Response\ApiDataResponse; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
|
||
class ApiDataMiddleware extends ApiMiddleware | ||
{ | ||
|
||
/** | ||
* @param ServerRequestInterface $psr7Request | ||
* @param ResponseInterface $psr7Response | ||
* @return ApiDataResponse | ||
*/ | ||
protected function createApiResponse(ServerRequestInterface $psr7Request, ResponseInterface $psr7Response) | ||
{ | ||
return (new ApiDataResponse())->withPsr7($psr7Response); | ||
} | ||
|
||
} |
Oops, something went wrong.