Skip to content

Commit a1abcbc

Browse files
authored
perf(laravel): memoize the Symfony RouteCollection in Router (#8342)
Closes #8337
1 parent 7bc11b2 commit a1abcbc

3 files changed

Lines changed: 52 additions & 2 deletions

File tree

src/Laravel/Routing/Router.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ final class Router implements RouterInterface, UrlGeneratorInterface
3737
];
3838

3939
private RequestContext $context;
40+
private ?RouteCollection $routeCollection = null;
4041

4142
public function __construct(private readonly BaseRouter $router, private readonly int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH)
4243
{
@@ -63,10 +64,14 @@ public function getContext(): RequestContext
6364
*/
6465
public function getRouteCollection(): RouteCollection
6566
{
67+
if (null !== $this->routeCollection) {
68+
return $this->routeCollection;
69+
}
70+
6671
/** @var \Illuminate\Routing\RouteCollection $routes */
6772
$routes = $this->router->getRoutes();
6873

69-
return $routes->toSymfonyRouteCollection();
74+
return $this->routeCollection = $routes->toSymfonyRouteCollection();
7075
}
7176

7277
/**

src/Laravel/Routing/SkolemIriConverter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\Metadata\IriConverterInterface;
1818
use ApiPlatform\Metadata\Operation;
1919
use ApiPlatform\Metadata\UrlGeneratorInterface;
20+
use Symfony\Component\Routing\RouterInterface;
2021

2122
/**
2223
* {@inheritdoc}
@@ -37,7 +38,7 @@ final class SkolemIriConverter implements IriConverterInterface
3738
*/
3839
private array $classHashMap = [];
3940

40-
public function __construct(private readonly Router $router)
41+
public function __construct(private readonly RouterInterface $router)
4142
{
4243
$this->objectHashMap = new \SplObjectStorage();
4344
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Tests\Unit\Routing;
15+
16+
use ApiPlatform\Laravel\Routing\Router;
17+
use Illuminate\Routing\RouteCollection as IlluminateRouteCollection;
18+
use Illuminate\Routing\Router as BaseRouter;
19+
use PHPUnit\Framework\TestCase;
20+
use Symfony\Component\Routing\RouteCollection;
21+
22+
class RouterTest extends TestCase
23+
{
24+
public function testGetRouteCollectionIsMemoizedAcrossCalls(): void
25+
{
26+
$symfonyRoutes = new RouteCollection();
27+
28+
$illuminateRoutes = $this->createMock(IlluminateRouteCollection::class);
29+
$illuminateRoutes->expects($this->once())
30+
->method('toSymfonyRouteCollection')
31+
->willReturn($symfonyRoutes);
32+
33+
$baseRouter = $this->createStub(BaseRouter::class);
34+
$baseRouter->method('getRoutes')->willReturn($illuminateRoutes);
35+
36+
$router = new Router($baseRouter);
37+
38+
$first = $router->getRouteCollection();
39+
$second = $router->getRouteCollection();
40+
41+
$this->assertSame($symfonyRoutes, $first);
42+
$this->assertSame($first, $second);
43+
}
44+
}

0 commit comments

Comments
 (0)