Skip to content

Instantly share code, notes, and snippets.

@n1215
Last active December 2, 2017 06:50
Show Gist options
  • Save n1215/240612539cd1e2b85b4e57d751c43ac3 to your computer and use it in GitHub Desktop.
Save n1215/240612539cd1e2b85b4e57d751c43ac3 to your computer and use it in GitHub Desktop.
PSR-7 / psr-15 ルータ
<?php
interface RouterInterface {
public function match(): RoutingResultInterface;
}
interface RoutingResultInterface {
public function getHandler(): ?RouteInterface;
public function getParams(): array;
public function isSuccess(): bool;
public function getError(): ?RoutingErrorInterface;
}
interface RoutingErrorInterface {
public function getErrorCode(): int;
public function getMessage(): string;
}
interface RoutingErrorResponderInterface {
public function respond(RoutingErrorInterface $error): ResponseInterface;
}
class RouterHandler implements RequestHandlerInterface
{
public function __construct(RouterInterface $router, RoutingErrorResponderInterface $errorResponder)
{
$this->router = $router;
$this->errorResponder = $errorResponder;
}
public function process(ServerRequestInterface $request): ResponseInterface
{
$result = $this->router->match($request);
if (!$result->isSuccess()) {
return $this->errorResponder->respond($result->getError());
}
$request->withAttribute(self::class, $result->getParams());
return $reult->getHandler()->handle($request);
}
}
/////////////////// usage
////// utils
// RequestHandlerをMiddlewareで包んだRequestHandlerを作成する
function handler(string $coreHandlerClass, array $middlewareClasses = []): RequestHandlerInterface
{
return new RequestHandler($coreHandlerClasses, $middlewareClasses);
}
class MethodAndPathMatcher implements RequestMatcherInterface {
// implements
}
class Path {
public static function get(string $path): RequestMatcherInterface
{
return new MethodAndPathMatcher('GET', $path);
}
public static function post(string $path): RequestMatcherInterface
{
return new MethodAndPathMatcher('POST', $path);
}
}
////// entry point
$container = new PSR11Container();
// $container->register()
$routeMap = new RouteMap([
new Route('get_endpoint_name', Path::get('/test/get/'), handler(GetTestAction::class, [RouteMiddlewareA::class])),
new Route('post_endpoint_name', Path::post('/test/post/'), handler(PostTestAction::class, [RouteMiddlewareB::class, RouteMiddlewareD::class])),
]);
$router = new Router($routeMap); // implements RouterInterface
$handler = new RouterHandler($router, new RoutingErrorResponder());
$response = $handler->($request);
///memo/////////////////////////////////////////
// Routeのinterfaceは表に出さない方が良さそう。Routerの実装時の参考。
interface RequestMatchResultInterface {
public function getParams(): array;
public function isSuccess(): bool;
}
interface ServerRequestMatcherInterface {
public function match(ServerRequestInterface $request): RequestMatchResultInterface;
}
interface RouteInterface {
public function getName(): string;
public function match(): RequestMatchResultInterface;
public function getHandler(): RequestHandlerInterface;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment