Skip to content

Commit 4e8e5c3

Browse files
authored
Merge pull request #8 from Tobion/route-priority
add support for route priorities
2 parents f5ea1e1 + 156c964 commit 4e8e5c3

File tree

4 files changed

+108
-2
lines changed

4 files changed

+108
-2
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,30 @@ The above example will create a route `/foobar.{_format}` where the format is op
126126
You can also enable the format-suffix globally by configuring it on the root Swagger annotation and disable it for
127127
certain routes again, see [test fixtures](./tests/Fixtures/FormatSuffix/Controller.php).
128128

129+
### Order routes with priority
130+
131+
Since Symfony 5.1, the order of routes defined using annotations can be [influenced using a priority](https://symfony.com/doc/current/routing.html#priority-parameter).
132+
This can be used to make sure templated routes do not match before concrete routes without parameters for the same URL.
133+
The priority can also be set on OpenAPI annotations using a `priority` vendor extension:
134+
135+
```php
136+
use Swagger\Annotations as SWG;
137+
138+
class MyController
139+
{
140+
/**
141+
* @SWG\Get(
142+
* path="/foobar",
143+
* x={"priority": 10},
144+
* @SWG\Response(response="200", description="Success")
145+
* )
146+
*/
147+
public function __invoke()
148+
{
149+
}
150+
}
151+
```
152+
129153
## Contributing
130154

131155
To run tests:

src/OpenApiRouteLoader.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ private function addRouteFromOpenApiOperation(RouteCollection $routeCollection,
7575
$controller = $this->getControllerFromOpenApiOperation($operation);
7676
$name = $this->getRouteName($operation, $controller);
7777
$route = $this->createRoute($operation, $controller, $parentFormatSuffixConfig);
78-
$routeCollection->add($name, $route);
78+
$priority = $this->getRoutePriority($operation);
79+
$routeCollection->add($name, $route, $priority);
7980
}
8081

8182
private function createRoute(Operation $operation, string $controller, FormatSuffixConfig $parentFormatSuffixConfig): Route
@@ -117,6 +118,15 @@ private function getRouteName(Operation $operation, string $controller): string
117118
return \Swagger\UNDEFINED === $operation->operationId ? $this->getDefaultRouteName($controller) : $operation->operationId;
118119
}
119120

121+
private function getRoutePriority(Operation $operation): int
122+
{
123+
if (isset($operation->x['priority']) && is_int($operation->x['priority'])) {
124+
return $operation->x['priority'];
125+
}
126+
127+
return 0;
128+
}
129+
120130
/**
121131
* @see \Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader::getDefaultRouteName
122132
*/
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tobion\OpenApiSymfonyRouting\Tests\Fixtures\Priority;
6+
7+
use Swagger\Annotations as SWG;
8+
9+
/**
10+
* @SWG\Swagger(
11+
* @SWG\Info(title="My API", version="1.0")
12+
* )
13+
*/
14+
class Controller
15+
{
16+
/**
17+
* @SWG\Get(
18+
* path="/foo",
19+
* @SWG\Response(response="200", description="Success")
20+
* )
21+
*/
22+
public function foo(): void
23+
{
24+
}
25+
26+
/**
27+
* @SWG\Get(
28+
* path="/{catchall}",
29+
* x={"priority": -100},
30+
* @SWG\Response(response="200", description="Success")
31+
* )
32+
*/
33+
public function catchall(): void
34+
{
35+
}
36+
37+
/**
38+
* @SWG\Get(
39+
* path="/bar",
40+
* x={"priority": 10},
41+
* @SWG\Response(response="200", description="Success")
42+
* )
43+
*/
44+
public function bar(): void
45+
{
46+
}
47+
}

tests/OpenApiRouteLoaderTest.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
use PHPUnit\Framework\TestCase;
88
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;
9-
use Symfony\Component\Finder\Finder;
109
use Symfony\Component\Routing\Route;
1110
use Symfony\Component\Routing\RouteCollection;
1211
use Tobion\OpenApiSymfonyRouting\OpenApiRouteLoader;
1312
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\Basic\Controller as BasicController;
1413
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\FormatSuffix\Controller as FormatSuffixController;
1514
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\OperationId\Controller as OperationIdController;
1615
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\PathParameterPattern\Controller as PathParameterPatternController;
16+
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\Priority\Controller as PriorityController;
1717
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\SeveralClasses\BarController;
1818
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\SeveralClasses\FooController;
1919
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\SeveralClasses\SubNamespace\SubController;
@@ -97,6 +97,31 @@ public function testPathParameterPattern(): void
9797
self::assertEquals($expectedRoutes, $routes);
9898
}
9999

100+
public function testPriority(): void
101+
{
102+
$routeLoader = OpenApiRouteLoader::fromDirectories(__DIR__.'/Fixtures/Priority');
103+
104+
$routes = $routeLoader->__invoke();
105+
106+
$expectedRoutes = new RouteCollection();
107+
$expectedRoutes->add(
108+
self::FIXTURES_ROUTE_NAME_PREFIX.'priority_foo',
109+
(new Route('/foo'))->setMethods('GET')->setDefault('_controller', PriorityController::class.'::foo')
110+
);
111+
$expectedRoutes->add(
112+
self::FIXTURES_ROUTE_NAME_PREFIX.'priority_catchall',
113+
(new Route('/{catchall}'))->setMethods('GET')->setDefault('_controller', PriorityController::class.'::catchall'),
114+
-100
115+
);
116+
$expectedRoutes->add(
117+
self::FIXTURES_ROUTE_NAME_PREFIX.'priority_bar',
118+
(new Route('/bar'))->setMethods('GET')->setDefault('_controller', PriorityController::class.'::bar'),
119+
10
120+
);
121+
122+
self::assertEquals($expectedRoutes, $routes);
123+
}
124+
100125
public function testSeveralClasses(): void
101126
{
102127
$routeLoader = OpenApiRouteLoader::fromDirectories(__DIR__.'/Fixtures/SeveralClasses');

0 commit comments

Comments
 (0)