From 24cc28cb07ca10eaf8d76aaecca4514505ce1576 Mon Sep 17 00:00:00 2001 From: Petr Hejna Date: Tue, 20 Mar 2018 14:00:20 +0100 Subject: [PATCH 1/2] Revert "Revert "Global app middlewares and multiple action methods"" --- README.md | 9 +++-- src/SlimApplicationFactory.php | 52 ++++++++++++++++++++++++---- tests/Dummy/AllRouteMiddleware.php | 24 +++++++++++++ tests/Dummy/AppMiddleware.php | 24 +++++++++++++ tests/SlimApplicationFactoryTest.php | 22 +++++++++++- tests/config.neon | 9 +++++ 6 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 tests/Dummy/AllRouteMiddleware.php create mode 100644 tests/Dummy/AppMiddleware.php diff --git a/README.md b/README.md index 9207c25..50e00fd 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ slimApi: # Configure it ``` -### First API enpoint +### First API endpoint Now let's say you want to make a REST endpoint creating channels, `[POST] /new-api/2.0/channels` You need to define in `parameters.api` section in `config.neon`. @@ -71,7 +71,12 @@ parameters: - App\SomeOtherMiddleware # last in row - App\UsuallyRequestDataValidationMiddleware # second in row - App\SomeAuthMiddleware # this one is called first - + + globalMiddlewares: + - App\SomeGlobalMiddleware # this is called for each route, before route middlewares + + appMiddlewares: + - App\SomeAppMiddleware # this is called for each request ``` You can also reference the named service by it's name. diff --git a/src/SlimApplicationFactory.php b/src/SlimApplicationFactory.php index b669e29..61b17b8 100644 --- a/src/SlimApplicationFactory.php +++ b/src/SlimApplicationFactory.php @@ -22,6 +22,11 @@ final class SlimApplicationFactory */ private $container; + /** + * @var Middleware[] + */ + private $globalMiddlewares; + /** * @param array $configuration * @param Container $container @@ -30,6 +35,7 @@ public function __construct(array $configuration, Container $container) { $this->configuration = $configuration; $this->container = $container; + $this->globalMiddlewares = []; } /** @@ -41,6 +47,8 @@ public function create() $configuration = $this->getConfiguration($this->configuration['apiDefinitionKey']); + $this->registerGlobalMiddlewares($app, $configuration); + foreach ($configuration['routes'] as $apiName => $api) { $this->registerApis($app, $api, $apiName); } @@ -55,6 +63,12 @@ public function create() $this->registerHandlers($app, $configuration['handlers']); } + if (isset($configuration['appMiddlewares'])) { + foreach ($configuration['appMiddlewares'] as $globalMiddleware) { + $this->registerAppMiddleware($app, $globalMiddleware); + } + } + return $app; } @@ -146,7 +160,9 @@ private function registerHandlers(SlimApp $app, array $handlers) */ private function registerServiceIntoContainer(SlimApp $app, $serviceName) { - $app->getContainer()[$serviceName] = $this->getServiceProvider($serviceName); + if (!$app->getContainer()->has($serviceName)) { + $app->getContainer()[$serviceName] = $this->getServiceProvider($serviceName); + } } /** @@ -212,15 +228,15 @@ private function registerInvokableActionRoutes(SlimApp $app, array $routeData, $ if (isset($config['middleware']) && count($config['middleware']) > 0) { foreach ($config['middleware'] as $middleware) { - $container = $app->getContainer(); - - if (!$container->has($middleware)) { - $this->registerServiceIntoContainer($app, $middleware); - } + $this->registerServiceIntoContainer($app, $middleware); $routeToAdd->add($middleware); } } + + foreach ($this->globalMiddlewares as $globalMiddleware) { + $routeToAdd->add($globalMiddleware); + } } } @@ -235,4 +251,28 @@ private function createUrlPattern($apiName, $version, $routeName) return sprintf('/%s/%s%s', $apiName, $version, $routeName); } + /** + * @param SlimApp $app + * @param string $middleware + */ + private function registerAppMiddleware(SlimApp $app, $middleware) + { + $this->registerServiceIntoContainer($app, $middleware); + + $app->add($middleware); + } + + /** + * @param SlimApp $app + * @param array $configuration + */ + private function registerGlobalMiddlewares(SlimApp $app, $configuration) + { + if (isset($configuration['globalMiddlewares']) && count($configuration['globalMiddlewares']) > 0) { + foreach ($configuration['globalMiddlewares'] as $globalMiddleware) { + $this->registerServiceIntoContainer($app, $globalMiddleware); + $this->globalMiddlewares[] = $app->getContainer()->get($globalMiddleware); + } + } + } } diff --git a/tests/Dummy/AllRouteMiddleware.php b/tests/Dummy/AllRouteMiddleware.php new file mode 100644 index 0000000..1bbbdd5 --- /dev/null +++ b/tests/Dummy/AllRouteMiddleware.php @@ -0,0 +1,24 @@ +withAddedHeader('processed-by-all-route-middleware', 'correct'); + + return $next($request, $response); + } +} diff --git a/tests/Dummy/AppMiddleware.php b/tests/Dummy/AppMiddleware.php new file mode 100644 index 0000000..ddcd24c --- /dev/null +++ b/tests/Dummy/AppMiddleware.php @@ -0,0 +1,24 @@ +withAddedHeader('processed-by-app-middleware', 'correct'); + + return $next($request, $response); + } +} diff --git a/tests/SlimApplicationFactoryTest.php b/tests/SlimApplicationFactoryTest.php index c502abb..c47a497 100644 --- a/tests/SlimApplicationFactoryTest.php +++ b/tests/SlimApplicationFactoryTest.php @@ -7,7 +7,6 @@ use BrandEmbassy\Slim\SlimApplicationFactory; use BrandEmbassy\Slim\Request\Request; use BrandEmbassy\Slim\Response\Response; -use LogicException; use Nette\DI\Compiler; use Nette\DI\Container; use Nette\DI\ContainerLoader; @@ -87,6 +86,27 @@ public function testShouldAllowRequestByAccessMiddleware() $this->assertEquals('{"channelId":"fb_1234"}', $this->getContents($response)); } + public function testShouldHaveHeaderByGlobalMiddleware() + { + $request = $this->createRequest('POST', '/new-api/2.0/channels'); + + /** @var ResponseInterface $response */ + $response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response())); + + $this->assertEquals(['correct'], $response->getHeader('processed-by-all-route-middleware')); + $this->assertEquals(['correct'], $response->getHeader('processed-by-app-middleware')); + } + + public function testShouldProcessedByAppMiddleware() + { + $request = $this->createRequest('POST', '/non-existing/path'); + + /** @var ResponseInterface $response */ + $response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response())); + + $this->assertEquals(['correct'], $response->getHeader('processed-by-app-middleware')); + } + /** * @param string $configPath * @return Container diff --git a/tests/config.neon b/tests/config.neon index 66ae14a..2fcfc5d 100644 --- a/tests/config.neon +++ b/tests/config.neon @@ -9,6 +9,8 @@ services: - BrandEmbassyTest\Slim\Dummy\GoldenKeyAuthMiddleware - BrandEmbassyTest\Slim\Dummy\CreateChannelAction - BrandEmbassyTest\Slim\Dummy\ErroringAction + - BrandEmbassyTest\Slim\Dummy\AllRouteMiddleware + - BrandEmbassyTest\Slim\Dummy\AppMiddleware parameters: api: @@ -30,6 +32,13 @@ parameters: post: service: BrandEmbassyTest\Slim\Dummy\ErroringAction + globalMiddlewares: + - BrandEmbassyTest\Slim\Dummy\AllRouteMiddleware + + appMiddlewares: + - BrandEmbassyTest\Slim\Dummy\AppMiddleware + + slimApi: slimConfiguration: settings: From 03fd24562eb8eaabf0b6b4f4e614129b3e7eafde Mon Sep 17 00:00:00 2001 From: Petr Hejna Date: Mon, 1 Oct 2018 09:14:52 +0200 Subject: [PATCH 2/2] better naming for global middlewares --- README.md | 14 +++++---- src/SlimApplicationFactory.php | 29 +++++++++---------- ...leware.php => BeforeRequestMiddleware.php} | 7 +++-- ...ddleware.php => BeforeRouteMiddleware.php} | 7 +++-- tests/SlimApplicationFactoryTest.php | 20 +++++++++---- tests/config.neon | 12 ++++---- 6 files changed, 53 insertions(+), 36 deletions(-) rename tests/Dummy/{AppMiddleware.php => BeforeRequestMiddleware.php} (71%) rename tests/Dummy/{AllRouteMiddleware.php => BeforeRouteMiddleware.php} (71%) diff --git a/README.md b/README.md index 50e00fd..b53734c 100644 --- a/README.md +++ b/README.md @@ -71,12 +71,14 @@ parameters: - App\SomeOtherMiddleware # last in row - App\UsuallyRequestDataValidationMiddleware # second in row - App\SomeAuthMiddleware # this one is called first - - globalMiddlewares: - - App\SomeGlobalMiddleware # this is called for each route, before route middlewares - - appMiddlewares: - - App\SomeAppMiddleware # this is called for each request + + beforeRouteMiddlewares: + # this is called for each route, before route middlewares + - App\SomeBeforeRequestMiddleware + + beforeRequestMiddlewares: + # this is called for each request, even when route does NOT exist (404 requests) + - App\SomeBeforeRouteMiddleware tests/Dummy/BeforeRequestMiddleware.php ``` You can also reference the named service by it's name. diff --git a/src/SlimApplicationFactory.php b/src/SlimApplicationFactory.php index 61b17b8..687e50c 100644 --- a/src/SlimApplicationFactory.php +++ b/src/SlimApplicationFactory.php @@ -25,7 +25,7 @@ final class SlimApplicationFactory /** * @var Middleware[] */ - private $globalMiddlewares; + private $beforeRoutesMiddlewares; /** * @param array $configuration @@ -35,7 +35,7 @@ public function __construct(array $configuration, Container $container) { $this->configuration = $configuration; $this->container = $container; - $this->globalMiddlewares = []; + $this->beforeRoutesMiddlewares = []; } /** @@ -47,7 +47,7 @@ public function create() $configuration = $this->getConfiguration($this->configuration['apiDefinitionKey']); - $this->registerGlobalMiddlewares($app, $configuration); + $this->registerBeforeRouteMiddlewares($app, $configuration); foreach ($configuration['routes'] as $apiName => $api) { $this->registerApis($app, $api, $apiName); @@ -63,9 +63,9 @@ public function create() $this->registerHandlers($app, $configuration['handlers']); } - if (isset($configuration['appMiddlewares'])) { - foreach ($configuration['appMiddlewares'] as $globalMiddleware) { - $this->registerAppMiddleware($app, $globalMiddleware); + if (isset($configuration['beforeRequestMiddlewares'])) { + foreach ($configuration['beforeRequestMiddlewares'] as $middleware) { + $this->registerBeforeRequestMiddleware($app, $middleware); } } @@ -226,7 +226,7 @@ private function registerInvokableActionRoutes(SlimApp $app, array $routeData, $ $this->registerServiceIntoContainer($app, $service); $routeToAdd = $app->map([$method], $urlPattern, $service); - if (isset($config['middleware']) && count($config['middleware']) > 0) { + if (isset($config['middleware'])) { foreach ($config['middleware'] as $middleware) { $this->registerServiceIntoContainer($app, $middleware); @@ -234,8 +234,8 @@ private function registerInvokableActionRoutes(SlimApp $app, array $routeData, $ } } - foreach ($this->globalMiddlewares as $globalMiddleware) { - $routeToAdd->add($globalMiddleware); + foreach ($this->beforeRoutesMiddlewares as $middleware) { + $routeToAdd->add($middleware); } } } @@ -255,10 +255,9 @@ private function createUrlPattern($apiName, $version, $routeName) * @param SlimApp $app * @param string $middleware */ - private function registerAppMiddleware(SlimApp $app, $middleware) + private function registerBeforeRequestMiddleware(SlimApp $app, $middleware) { $this->registerServiceIntoContainer($app, $middleware); - $app->add($middleware); } @@ -266,12 +265,12 @@ private function registerAppMiddleware(SlimApp $app, $middleware) * @param SlimApp $app * @param array $configuration */ - private function registerGlobalMiddlewares(SlimApp $app, $configuration) + private function registerBeforeRouteMiddlewares(SlimApp $app, $configuration) { - if (isset($configuration['globalMiddlewares']) && count($configuration['globalMiddlewares']) > 0) { - foreach ($configuration['globalMiddlewares'] as $globalMiddleware) { + if (isset($configuration['beforeRouteMiddlewares'])) { + foreach ($configuration['beforeRouteMiddlewares'] as $globalMiddleware) { $this->registerServiceIntoContainer($app, $globalMiddleware); - $this->globalMiddlewares[] = $app->getContainer()->get($globalMiddleware); + $this->beforeRoutesMiddlewares[] = $app->getContainer()->get($globalMiddleware); } } } diff --git a/tests/Dummy/AppMiddleware.php b/tests/Dummy/BeforeRequestMiddleware.php similarity index 71% rename from tests/Dummy/AppMiddleware.php rename to tests/Dummy/BeforeRequestMiddleware.php index ddcd24c..72338b4 100644 --- a/tests/Dummy/AppMiddleware.php +++ b/tests/Dummy/BeforeRequestMiddleware.php @@ -6,7 +6,7 @@ use BrandEmbassy\Slim\Request\RequestInterface; use BrandEmbassy\Slim\Response\ResponseInterface; -class AppMiddleware implements Middleware +class BeforeRequestMiddleware implements Middleware { /** @@ -17,7 +17,10 @@ class AppMiddleware implements Middleware */ public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next) { - $response = $response->withAddedHeader('processed-by-app-middleware', 'correct'); + $response = $response->withAddedHeader( + 'processed-by-before-request-middleware', + 'proof-for-before-request' + ); return $next($request, $response); } diff --git a/tests/Dummy/AllRouteMiddleware.php b/tests/Dummy/BeforeRouteMiddleware.php similarity index 71% rename from tests/Dummy/AllRouteMiddleware.php rename to tests/Dummy/BeforeRouteMiddleware.php index 1bbbdd5..e8b1fe3 100644 --- a/tests/Dummy/AllRouteMiddleware.php +++ b/tests/Dummy/BeforeRouteMiddleware.php @@ -6,7 +6,7 @@ use BrandEmbassy\Slim\Request\RequestInterface; use BrandEmbassy\Slim\Response\ResponseInterface; -class AllRouteMiddleware implements Middleware +class BeforeRouteMiddleware implements Middleware { /** @@ -17,7 +17,10 @@ class AllRouteMiddleware implements Middleware */ public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next) { - $response = $response->withAddedHeader('processed-by-all-route-middleware', 'correct'); + $response = $response->withAddedHeader( + 'processed-by-before-route-middlewares', + 'proof-for-before-route' + ); return $next($request, $response); } diff --git a/tests/SlimApplicationFactoryTest.php b/tests/SlimApplicationFactoryTest.php index c47a497..a9c6040 100644 --- a/tests/SlimApplicationFactoryTest.php +++ b/tests/SlimApplicationFactoryTest.php @@ -86,25 +86,35 @@ public function testShouldAllowRequestByAccessMiddleware() $this->assertEquals('{"channelId":"fb_1234"}', $this->getContents($response)); } - public function testShouldHaveHeaderByGlobalMiddleware() + public function testShouldProcessBothGlobalMiddlewares() { $request = $this->createRequest('POST', '/new-api/2.0/channels'); /** @var ResponseInterface $response */ $response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response())); - $this->assertEquals(['correct'], $response->getHeader('processed-by-all-route-middleware')); - $this->assertEquals(['correct'], $response->getHeader('processed-by-app-middleware')); + $this->assertEquals( + ['proof-for-before-request'], + $response->getHeader('processed-by-before-request-middleware') + ); + + $this->assertEquals( + ['proof-for-before-route'], + $response->getHeader('processed-by-before-route-middlewares') + ); } - public function testShouldProcessedByAppMiddleware() + public function testShouldProcessBeforeRequestMiddleware() { $request = $this->createRequest('POST', '/non-existing/path'); /** @var ResponseInterface $response */ $response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response())); - $this->assertEquals(['correct'], $response->getHeader('processed-by-app-middleware')); + $this->assertEquals( + ['proof-for-before-request'], + $response->getHeader('processed-by-before-request-middleware') + ); } /** diff --git a/tests/config.neon b/tests/config.neon index 2fcfc5d..f78d01f 100644 --- a/tests/config.neon +++ b/tests/config.neon @@ -9,8 +9,8 @@ services: - BrandEmbassyTest\Slim\Dummy\GoldenKeyAuthMiddleware - BrandEmbassyTest\Slim\Dummy\CreateChannelAction - BrandEmbassyTest\Slim\Dummy\ErroringAction - - BrandEmbassyTest\Slim\Dummy\AllRouteMiddleware - - BrandEmbassyTest\Slim\Dummy\AppMiddleware + - BrandEmbassyTest\Slim\Dummy\BeforeRequestMiddleware + - BrandEmbassyTest\Slim\Dummy\BeforeRouteMiddleware parameters: api: @@ -32,11 +32,11 @@ parameters: post: service: BrandEmbassyTest\Slim\Dummy\ErroringAction - globalMiddlewares: - - BrandEmbassyTest\Slim\Dummy\AllRouteMiddleware + beforeRouteMiddlewares: + - BrandEmbassyTest\Slim\Dummy\BeforeRouteMiddleware - appMiddlewares: - - BrandEmbassyTest\Slim\Dummy\AppMiddleware + beforeRequestMiddlewares: + - BrandEmbassyTest\Slim\Dummy\BeforeRequestMiddleware slimApi: