Skip to content

Commit

Permalink
feat: Router now also handle its response
Browse files Browse the repository at this point in the history
Part of #18

Instead of returning the response object and handle it externally,
Router keeps it, and then handle it in a second method
  • Loading branch information
Gashmob committed May 27, 2024
1 parent 469c8f2 commit eca776b
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

use Psr\Http\Message\ResponseInterface;

final class ResponseHandler
/**
* @internal
*/
final class FinalResponseHandler
{
public function writeResponse(ResponseInterface $response): void
{
Expand Down
36 changes: 36 additions & 0 deletions include/ResponseHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* MIT License
*
* Copyright (c) 2024-Present Kevin Traini
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

declare(strict_types=1);

namespace Archict\Router;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

interface ResponseHandler
{
public function handleResponse(ResponseInterface $response, ServerRequestInterface $request): ResponseInterface;
}
22 changes: 18 additions & 4 deletions include/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Archict\Router\Exception\FailedToCreateRouteException;
use Archict\Router\Exception\HTTP\HTTPException;
use Archict\Router\Exception\RouterException;
use Archict\Router\HTTP\FinalResponseHandler;
use Archict\Router\Route\MiddlewareInformation;
use Archict\Router\Route\RouteCollection;
use Archict\Router\Route\RouteInformation;
Expand All @@ -18,10 +19,12 @@
use CuyZ\Valinor\Normalizer\Format;
use CuyZ\Valinor\Normalizer\Normalizer;
use GuzzleHttp\Psr7\HttpFactory;
use LogicException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;
use Throwable;

#[Service]
final class Router
Expand All @@ -30,6 +33,7 @@ final class Router
private readonly TreeMapper $mapper;
private readonly Normalizer $normalizer;
private RouteCollection $route_collection;
private ?ResponseInterface $response;

public function __construct(
private readonly EventDispatcher $event_dispatcher,
Expand All @@ -43,7 +47,7 @@ public function __construct(
* @throws RouterException
* @throws InvalidArgumentException
*/
public function route(ServerRequestInterface $request): ResponseInterface
public function route(ServerRequestInterface $request): void
{
$this->loadRoutes();

Expand All @@ -58,12 +62,22 @@ public function route(ServerRequestInterface $request): ResponseInterface
$request,
);

$response = $this->handleRoute($route, $request);
$this->response = $this->handleRoute($route, $request);
} catch (HTTPException $exception) {
$response = $exception->toResponse();
$this->response = $exception->toResponse();
} catch (Throwable $throwable) {
$this->response = HTTPExceptionFactory::ServerError($throwable->getMessage())->toResponse();
}
}

return $response;
public function response(): void
{
if ($this->response === null) {
throw new LogicException('You should call Router::route() before');
}

$final_handler = new FinalResponseHandler();
$final_handler->writeResponse($this->response);
}

private function handleMiddleware(MiddlewareInformation $middleware, ServerRequestInterface $request): ServerRequestInterface
Expand Down
26 changes: 3 additions & 23 deletions tests/unit/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,15 @@
namespace Archict\Router;

use Archict\Core\Core;
use Archict\Core\Services\ServiceManager;
use GuzzleHttp\Psr7\ServerRequest;
use PHPUnit\Framework\TestCase;

final class RouterTest extends TestCase
{
private ServiceManager $service_manager;
private Router $router;

protected function setUp(): void
public function testRouterIsLoaded(): void
{
$core = Core::build();
$core->load();
$this->service_manager = $core->service_manager;

$router = $this->service_manager->get(Router::class);
self::assertNotNull($router);
$this->router = $router;
}

public function testRouterIsLoaded(): void
{
self::assertTrue($this->service_manager->has(Router::class));
self::assertInstanceOf(Router::class, $this->service_manager->get(Router::class));
}

public function testItReturns404(): void
{
$response = $this->router->route(new ServerRequest('GET', 'route'));
self::assertSame(404, $response->getStatusCode());
self::assertTrue($core->service_manager->has(Router::class));
self::assertInstanceOf(Router::class, $core->service_manager->get(Router::class));
}
}

0 comments on commit eca776b

Please sign in to comment.