Skip to content

Commit

Permalink
Merge pull request #8 from Tobion/route-priority
Browse files Browse the repository at this point in the history
add support for route priorities
  • Loading branch information
Tobion committed Apr 14, 2021
2 parents f5ea1e1 + 156c964 commit 4e8e5c3
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 2 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@ The above example will create a route `/foobar.{_format}` where the format is op
You can also enable the format-suffix globally by configuring it on the root Swagger annotation and disable it for
certain routes again, see [test fixtures](./tests/Fixtures/FormatSuffix/Controller.php).

### Order routes with priority

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).
This can be used to make sure templated routes do not match before concrete routes without parameters for the same URL.
The priority can also be set on OpenAPI annotations using a `priority` vendor extension:

```php
use Swagger\Annotations as SWG;

class MyController
{
/**
* @SWG\Get(
* path="/foobar",
* x={"priority": 10},
* @SWG\Response(response="200", description="Success")
* )
*/
public function __invoke()
{
}
}
```

## Contributing

To run tests:
Expand Down
12 changes: 11 additions & 1 deletion src/OpenApiRouteLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ private function addRouteFromOpenApiOperation(RouteCollection $routeCollection,
$controller = $this->getControllerFromOpenApiOperation($operation);
$name = $this->getRouteName($operation, $controller);
$route = $this->createRoute($operation, $controller, $parentFormatSuffixConfig);
$routeCollection->add($name, $route);
$priority = $this->getRoutePriority($operation);
$routeCollection->add($name, $route, $priority);
}

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

private function getRoutePriority(Operation $operation): int
{
if (isset($operation->x['priority']) && is_int($operation->x['priority'])) {
return $operation->x['priority'];
}

return 0;
}

/**
* @see \Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader::getDefaultRouteName
*/
Expand Down
47 changes: 47 additions & 0 deletions tests/Fixtures/Priority/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Tobion\OpenApiSymfonyRouting\Tests\Fixtures\Priority;

use Swagger\Annotations as SWG;

/**
* @SWG\Swagger(
* @SWG\Info(title="My API", version="1.0")
* )
*/
class Controller
{
/**
* @SWG\Get(
* path="/foo",
* @SWG\Response(response="200", description="Success")
* )
*/
public function foo(): void
{
}

/**
* @SWG\Get(
* path="/{catchall}",
* x={"priority": -100},
* @SWG\Response(response="200", description="Success")
* )
*/
public function catchall(): void
{
}

/**
* @SWG\Get(
* path="/bar",
* x={"priority": 10},
* @SWG\Response(response="200", description="Success")
* )
*/
public function bar(): void
{
}
}
27 changes: 26 additions & 1 deletion tests/OpenApiRouteLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

use PHPUnit\Framework\TestCase;
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Tobion\OpenApiSymfonyRouting\OpenApiRouteLoader;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\Basic\Controller as BasicController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\FormatSuffix\Controller as FormatSuffixController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\OperationId\Controller as OperationIdController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\PathParameterPattern\Controller as PathParameterPatternController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\Priority\Controller as PriorityController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\SeveralClasses\BarController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\SeveralClasses\FooController;
use Tobion\OpenApiSymfonyRouting\Tests\Fixtures\SeveralClasses\SubNamespace\SubController;
Expand Down Expand Up @@ -97,6 +97,31 @@ public function testPathParameterPattern(): void
self::assertEquals($expectedRoutes, $routes);
}

public function testPriority(): void
{
$routeLoader = OpenApiRouteLoader::fromDirectories(__DIR__.'/Fixtures/Priority');

$routes = $routeLoader->__invoke();

$expectedRoutes = new RouteCollection();
$expectedRoutes->add(
self::FIXTURES_ROUTE_NAME_PREFIX.'priority_foo',
(new Route('/foo'))->setMethods('GET')->setDefault('_controller', PriorityController::class.'::foo')
);
$expectedRoutes->add(
self::FIXTURES_ROUTE_NAME_PREFIX.'priority_catchall',
(new Route('/{catchall}'))->setMethods('GET')->setDefault('_controller', PriorityController::class.'::catchall'),
-100
);
$expectedRoutes->add(
self::FIXTURES_ROUTE_NAME_PREFIX.'priority_bar',
(new Route('/bar'))->setMethods('GET')->setDefault('_controller', PriorityController::class.'::bar'),
10
);

self::assertEquals($expectedRoutes, $routes);
}

public function testSeveralClasses(): void
{
$routeLoader = OpenApiRouteLoader::fromDirectories(__DIR__.'/Fixtures/SeveralClasses');
Expand Down

0 comments on commit 4e8e5c3

Please sign in to comment.