diff --git a/src/Laravel/Routing/Router.php b/src/Laravel/Routing/Router.php index e57e59bd0ba..76da146cb36 100644 --- a/src/Laravel/Routing/Router.php +++ b/src/Laravel/Routing/Router.php @@ -37,6 +37,7 @@ final class Router implements RouterInterface, UrlGeneratorInterface ]; private RequestContext $context; + private ?RouteCollection $routeCollection = null; public function __construct(private readonly BaseRouter $router, private readonly int $urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH) { @@ -63,10 +64,14 @@ public function getContext(): RequestContext */ public function getRouteCollection(): RouteCollection { + if (null !== $this->routeCollection) { + return $this->routeCollection; + } + /** @var \Illuminate\Routing\RouteCollection $routes */ $routes = $this->router->getRoutes(); - return $routes->toSymfonyRouteCollection(); + return $this->routeCollection = $routes->toSymfonyRouteCollection(); } /** diff --git a/src/Laravel/Routing/SkolemIriConverter.php b/src/Laravel/Routing/SkolemIriConverter.php index df0f41d61dd..e7b7daf0491 100644 --- a/src/Laravel/Routing/SkolemIriConverter.php +++ b/src/Laravel/Routing/SkolemIriConverter.php @@ -17,6 +17,7 @@ use ApiPlatform\Metadata\IriConverterInterface; use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\UrlGeneratorInterface; +use Symfony\Component\Routing\RouterInterface; /** * {@inheritdoc} @@ -37,7 +38,7 @@ final class SkolemIriConverter implements IriConverterInterface */ private array $classHashMap = []; - public function __construct(private readonly Router $router) + public function __construct(private readonly RouterInterface $router) { $this->objectHashMap = new \SplObjectStorage(); } diff --git a/src/Laravel/Tests/Unit/Routing/RouterTest.php b/src/Laravel/Tests/Unit/Routing/RouterTest.php new file mode 100644 index 00000000000..d8d7e84164b --- /dev/null +++ b/src/Laravel/Tests/Unit/Routing/RouterTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Laravel\Tests\Unit\Routing; + +use ApiPlatform\Laravel\Routing\Router; +use Illuminate\Routing\RouteCollection as IlluminateRouteCollection; +use Illuminate\Routing\Router as BaseRouter; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Routing\RouteCollection; + +class RouterTest extends TestCase +{ + public function testGetRouteCollectionIsMemoizedAcrossCalls(): void + { + $symfonyRoutes = new RouteCollection(); + + $illuminateRoutes = $this->createMock(IlluminateRouteCollection::class); + $illuminateRoutes->expects($this->once()) + ->method('toSymfonyRouteCollection') + ->willReturn($symfonyRoutes); + + $baseRouter = $this->createStub(BaseRouter::class); + $baseRouter->method('getRoutes')->willReturn($illuminateRoutes); + + $router = new Router($baseRouter); + + $first = $router->getRouteCollection(); + $second = $router->getRouteCollection(); + + $this->assertSame($symfonyRoutes, $first); + $this->assertSame($first, $second); + } +}