Skip to content

Commit 7ffe34a

Browse files
authored
Merge pull request #8 from shadowhand/fix/expanded-http-routing
2 parents 61600dd + 5484de9 commit 7ffe34a

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

src/Router.php

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,53 @@
44

55
use Psr\Http\Message\ServerRequestInterface;
66

7+
use function is_array;
8+
79
/**
810
* Reproduces API Gateway routing for local development.
911
*
1012
* @internal
1113
*/
1214
class Router
1315
{
16+
public static function fromServerlessConfig(array $serverlessConfig): self
17+
{
18+
$routes = [];
19+
foreach ($serverlessConfig['functions'] as $function) {
20+
$pattern = $function['events'][0]['httpApi'] ?? null;
21+
22+
if (! $pattern) {
23+
continue;
24+
}
25+
26+
if (is_array($pattern)) {
27+
$pattern = self::patternToString($pattern);
28+
}
29+
30+
$routes[$pattern] = $function['handler'];
31+
}
32+
33+
return new self($routes);
34+
}
35+
36+
private static function patternToString(array $pattern): string
37+
{
38+
$method = $pattern['method'] ?? '*';
39+
$path = $pattern['path'] ?? '*';
40+
41+
// Special "any" method MUST be converted to star.
42+
if ($method === 'any') {
43+
$method = '*';
44+
}
45+
46+
// Alternative catch-all MUST be converted to standard catch-all.
47+
if ($method === '*' && $path === '*') {
48+
return '*';
49+
}
50+
51+
return $method . ' ' . $path;
52+
}
53+
1454
/** @var array<string,string> */
1555
private array $routes;
1656

@@ -22,17 +62,6 @@ public function __construct(array $routes)
2262
$this->routes = $routes;
2363
}
2464

25-
public static function fromServerlessConfig(array $serverlessConfig): self
26-
{
27-
$routes = [];
28-
foreach ($serverlessConfig['functions'] as $function) {
29-
$pattern = $function['events'][0]['httpApi'] ?? null;
30-
if (! $pattern) continue;
31-
$routes[$pattern] = $function['handler'];
32-
}
33-
return new self($routes);
34-
}
35-
3665
/**
3766
* @return array{0: ?string, 1: ServerRequestInterface}
3867
*/
@@ -58,7 +87,7 @@ private function matchesMethod(ServerRequestInterface $request, string $method):
5887
{
5988
$method = strtolower($method);
6089

61-
return ($method === 'any') || ($method === strtolower($request->getMethod()));
90+
return ($method === '*') || ($method === strtolower($request->getMethod()));
6291
}
6392

6493
private function matchesPath(ServerRequestInterface $request, string $pathPattern): bool

tests/RouterTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Nyholm\Psr7\ServerRequest;
77
use PHPUnit\Framework\TestCase;
88
use Psr\Http\Message\ServerRequestInterface;
9+
use Symfony\Component\Yaml\Yaml;
910

1011
class RouterTest extends TestCase
1112
{
@@ -48,6 +49,30 @@ public function test routing path parameters(): void
4849
self::assertEquals('def', $router->match($this->request('GET', '/abc/def'))[0]);
4950
}
5051

52+
/**
53+
* @test
54+
*/
55+
public function test_routing_expanded_config(): void
56+
{
57+
$config = <<<YAML
58+
functions:
59+
api:
60+
handler: api.php
61+
events:
62+
- httpApi:
63+
method: '*'
64+
path: '*'
65+
YAML;
66+
67+
$config = Yaml::parse($config);
68+
$router = Router::fromServerlessConfig($config);
69+
70+
self::assertSame('api.php', $router->match($this->request('GET', '/'))[0]);
71+
self::assertSame('api.php', $router->match($this->request('POST', '/'))[0]);
72+
self::assertSame('api.php', $router->match($this->request('GET', '/tests/1'))[0]);
73+
self::assertSame('api.php', $router->match($this->request('PUT', '/tests/1'))[0]);
74+
}
75+
5176
private function request(string $method, string $path): ServerRequestInterface
5277
{
5378
return new ServerRequest($method, $path);

0 commit comments

Comments
 (0)