mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-03 08:09:25 +03:00
Merge pull request #1257 from phansys/ticket_1121
Allow to filter routes by host (#1121)
This commit is contained in:
commit
3698daa547
10
CHANGELOG.md
10
CHANGELOG.md
@ -7,6 +7,16 @@ CHANGELOG
|
|||||||
* Add a documentation form extension. Use the ``documentation`` option to define how a form field is documented.
|
* Add a documentation form extension. Use the ``documentation`` option to define how a form field is documented.
|
||||||
* Allow references to config definitions in controllers.
|
* Allow references to config definitions in controllers.
|
||||||
|
|
||||||
|
Config
|
||||||
|
* `nelmio_api_doc.areas` added support to filter by host patterns.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
nelmio_api_doc:
|
||||||
|
routes: [ host_patterns: [ ^api\. ] ]
|
||||||
|
```
|
||||||
|
|
||||||
|
* Added dependency for "symfony/options-resolver:^3.4.4|^4.0"
|
||||||
|
|
||||||
3.1.0 (2017-01-28)
|
3.1.0 (2017-01-28)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -48,10 +48,10 @@ final class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->arrayNode('areas')
|
->arrayNode('areas')
|
||||||
->info('Filter the routes that are documented')
|
->info('Filter the routes that are documented')
|
||||||
->defaultValue(['default' => ['path_patterns' => []]])
|
->defaultValue(['default' => ['path_patterns' => [], 'host_patterns' => []]])
|
||||||
->beforeNormalization()
|
->beforeNormalization()
|
||||||
->ifTrue(function ($v) {
|
->ifTrue(function ($v) {
|
||||||
return empty($v) or isset($v['path_patterns']);
|
return 0 === count($v) || isset($v['path_patterns']) || isset($v['host_patterns']);
|
||||||
})
|
})
|
||||||
->then(function ($v) {
|
->then(function ($v) {
|
||||||
return ['default' => $v];
|
return ['default' => $v];
|
||||||
@ -68,9 +68,15 @@ final class Configuration implements ConfigurationInterface
|
|||||||
->addDefaultsIfNotSet()
|
->addDefaultsIfNotSet()
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('path_patterns')
|
->arrayNode('path_patterns')
|
||||||
|
->defaultValue([])
|
||||||
->example(['^/api', '^/api(?!/admin)'])
|
->example(['^/api', '^/api(?!/admin)'])
|
||||||
->prototype('scalar')->end()
|
->prototype('scalar')->end()
|
||||||
->end()
|
->end()
|
||||||
|
->arrayNode('host_patterns')
|
||||||
|
->defaultValue([])
|
||||||
|
->example(['^api\.'])
|
||||||
|
->prototype('scalar')->end()
|
||||||
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
@ -66,7 +66,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
|
|||||||
new TaggedIteratorArgument('nelmio_api_doc.model_describer'),
|
new TaggedIteratorArgument('nelmio_api_doc.model_describer'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (0 === count($areaConfig['path_patterns'])) {
|
if (0 === count($areaConfig['path_patterns']) && 0 === count($areaConfig['host_patterns'])) {
|
||||||
$container->setDefinition(sprintf('nelmio_api_doc.routes.%s', $area), $routesDefinition)
|
$container->setDefinition(sprintf('nelmio_api_doc.routes.%s', $area), $routesDefinition)
|
||||||
->setPublic(false);
|
->setPublic(false);
|
||||||
} else {
|
} else {
|
||||||
@ -74,7 +74,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
|
|||||||
->setPublic(false)
|
->setPublic(false)
|
||||||
->setFactory([
|
->setFactory([
|
||||||
(new Definition(FilteredRouteCollectionBuilder::class))
|
(new Definition(FilteredRouteCollectionBuilder::class))
|
||||||
->addArgument($areaConfig['path_patterns']),
|
->addArgument($areaConfig),
|
||||||
'filter',
|
'filter',
|
||||||
])
|
])
|
||||||
->addArgument($routesDefinition);
|
->addArgument($routesDefinition);
|
||||||
|
@ -8,6 +8,7 @@ We've already seen that you can configure which routes are documented using ``ne
|
|||||||
nelmio_api_doc:
|
nelmio_api_doc:
|
||||||
areas:
|
areas:
|
||||||
path_patterns: [ ^/api ]
|
path_patterns: [ ^/api ]
|
||||||
|
host_patterns: [ ^api\. ]
|
||||||
|
|
||||||
But in fact, this config option is way more powerful and allows you to split your documentation in several parts.
|
But in fact, this config option is way more powerful and allows you to split your documentation in several parts.
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ You can define areas which will each generates a different documentation:
|
|||||||
areas:
|
areas:
|
||||||
default:
|
default:
|
||||||
path_patterns: [ ^/api ]
|
path_patterns: [ ^/api ]
|
||||||
|
host_patterns: [ ^api\. ]
|
||||||
internal:
|
internal:
|
||||||
path_patterns: [ ^/internal ]
|
path_patterns: [ ^/internal ]
|
||||||
commercial:
|
commercial:
|
||||||
|
@ -81,6 +81,8 @@ Open a command console, enter your project directory and execute the following c
|
|||||||
areas:
|
areas:
|
||||||
path_patterns: # an array of regexps
|
path_patterns: # an array of regexps
|
||||||
- ^/api(?!/doc$)
|
- ^/api(?!/doc$)
|
||||||
|
host_patterns:
|
||||||
|
- ^api\.
|
||||||
|
|
||||||
How does this bundle work?
|
How does this bundle work?
|
||||||
--------------------------
|
--------------------------
|
||||||
|
@ -11,23 +11,41 @@
|
|||||||
|
|
||||||
namespace Nelmio\ApiDocBundle\Routing;
|
namespace Nelmio\ApiDocBundle\Routing;
|
||||||
|
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
final class FilteredRouteCollectionBuilder
|
final class FilteredRouteCollectionBuilder
|
||||||
{
|
{
|
||||||
private $pathPatterns;
|
private $options;
|
||||||
|
|
||||||
public function __construct(array $pathPatterns = [])
|
public function __construct(array $options = [])
|
||||||
{
|
{
|
||||||
$this->pathPatterns = $pathPatterns;
|
$resolver = new OptionsResolver();
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'path_patterns' => [],
|
||||||
|
'host_patterns' => [],
|
||||||
|
])
|
||||||
|
->setAllowedTypes('path_patterns', 'string[]')
|
||||||
|
->setAllowedTypes('host_patterns', 'string[]')
|
||||||
|
;
|
||||||
|
|
||||||
|
if (array_key_exists(0, $options)) {
|
||||||
|
@trigger_error(sprintf('Passing an indexed array with a collection of path patterns as argument 1 for `%s()` is deprecated since 3.2.0, expected structure is an array containing parameterized options.', __METHOD__), E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
$normalizedOptions = ['path_patterns' => $options];
|
||||||
|
$options = $normalizedOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->options = $resolver->resolve($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function filter(RouteCollection $routes): RouteCollection
|
public function filter(RouteCollection $routes): RouteCollection
|
||||||
{
|
{
|
||||||
$filteredRoutes = new RouteCollection();
|
$filteredRoutes = new RouteCollection();
|
||||||
foreach ($routes->all() as $name => $route) {
|
foreach ($routes->all() as $name => $route) {
|
||||||
if ($this->match($route)) {
|
if ($this->matchPath($route) && $this->matchHost($route)) {
|
||||||
$filteredRoutes->add($name, $route);
|
$filteredRoutes->add($name, $route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,14 +53,25 @@ final class FilteredRouteCollectionBuilder
|
|||||||
return $filteredRoutes;
|
return $filteredRoutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function match(Route $route): bool
|
private function matchPath(Route $route): bool
|
||||||
{
|
{
|
||||||
foreach ($this->pathPatterns as $pathPattern) {
|
foreach ($this->options['path_patterns'] as $pathPattern) {
|
||||||
if (preg_match('{'.$pathPattern.'}', $route->getPath())) {
|
if (preg_match('{'.$pathPattern.'}', $route->getPath())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 0 === count($this->options['path_patterns']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function matchHost(Route $route): bool
|
||||||
|
{
|
||||||
|
foreach ($this->options['host_patterns'] as $hostPattern) {
|
||||||
|
if (preg_match('{'.$hostPattern.'}', $route->getHost())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 === count($this->options['host_patterns']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,19 +22,19 @@ class ConfigurationTest extends TestCase
|
|||||||
$processor = new Processor();
|
$processor = new Processor();
|
||||||
$config = $processor->processConfiguration(new Configuration(), [['areas' => ['path_patterns' => ['/foo']]]]);
|
$config = $processor->processConfiguration(new Configuration(), [['areas' => ['path_patterns' => ['/foo']]]]);
|
||||||
|
|
||||||
$this->assertEquals(['default' => ['path_patterns' => ['/foo']]], $config['areas']);
|
$this->assertSame(['default' => ['path_patterns' => ['/foo'], 'host_patterns' => []]], $config['areas']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAreas()
|
public function testAreas()
|
||||||
{
|
{
|
||||||
$processor = new Processor();
|
$processor = new Processor();
|
||||||
$config = $processor->processConfiguration(new Configuration(), [['areas' => $areas = [
|
$config = $processor->processConfiguration(new Configuration(), [['areas' => $areas = [
|
||||||
'default' => ['path_patterns' => ['/foo']],
|
'default' => ['path_patterns' => ['/foo'], 'host_patterns' => []],
|
||||||
'internal' => ['path_patterns' => ['/internal']],
|
'internal' => ['path_patterns' => ['/internal'], 'host_patterns' => ['^swagger\.']],
|
||||||
'commercial' => ['path_patterns' => ['/internal']],
|
'commercial' => ['path_patterns' => ['/internal'], 'host_patterns' => []],
|
||||||
]]]);
|
]]]);
|
||||||
|
|
||||||
$this->assertEquals($areas, $config['areas']);
|
$this->assertSame($areas, $config['areas']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +57,6 @@ class ConfigurationTest extends TestCase
|
|||||||
$processor = new Processor();
|
$processor = new Processor();
|
||||||
$config = $processor->processConfiguration(new Configuration(), [['routes' => ['path_patterns' => ['/foo']]]]);
|
$config = $processor->processConfiguration(new Configuration(), [['routes' => ['path_patterns' => ['/foo']]]]);
|
||||||
|
|
||||||
$this->assertEquals(['default' => ['path_patterns' => ['/foo']]], $config['areas']);
|
$this->assertSame(['default' => ['path_patterns' => ['/foo'], 'host_patterns' => []]], $config['areas']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
|||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/api")
|
* @Route("/api", host="api.example.com")
|
||||||
*/
|
*/
|
||||||
class ApiController
|
class ApiController
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,9 @@ use Nelmio\ApiDocBundle\Tests\Functional\Entity\VirtualProperty;
|
|||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route(host="api.example.com")
|
||||||
|
*/
|
||||||
class JMSController
|
class JMSController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -15,7 +15,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
|||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/test")
|
* @Route("/test", host="api-test.example.com")
|
||||||
*/
|
*/
|
||||||
class TestController
|
class TestController
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,9 @@ namespace Nelmio\ApiDocBundle\Tests\Functional\Controller;
|
|||||||
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route(host="api.example.com")
|
||||||
|
*/
|
||||||
class UndocumentedController
|
class UndocumentedController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -15,7 +15,7 @@ class SwaggerUiTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
protected static function createClient(array $options = [], array $server = [])
|
protected static function createClient(array $options = [], array $server = [])
|
||||||
{
|
{
|
||||||
return parent::createClient([], ['PHP_SELF' => '/app_dev.php/docs', 'SCRIPT_FILENAME' => '/var/www/app/web/app_dev.php']);
|
return parent::createClient([], $server + ['HTTP_HOST' => 'api.example.com', 'PHP_SELF' => '/app_dev.php/docs', 'SCRIPT_FILENAME' => '/var/www/app/web/app_dev.php']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,8 +116,8 @@ class TestKernel extends Kernel
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
'areas' => [
|
'areas' => [
|
||||||
'default' => ['path_patterns' => ['^/api(?!/admin)']],
|
'default' => ['path_patterns' => ['^/api(?!/admin)'], 'host_patterns' => ['^api\.']],
|
||||||
'test' => ['path_patterns' => ['^/test']],
|
'test' => ['path_patterns' => ['^/test'], 'host_patterns' => ['^api-test\.']],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
|
|
||||||
protected function getSwaggerDefinition()
|
protected function getSwaggerDefinition()
|
||||||
{
|
{
|
||||||
static::createClient();
|
static::createClient([], ['HTTP_HOST' => 'api.example.com']);
|
||||||
|
|
||||||
return static::$kernel->getContainer()->get('nelmio_api_doc.generator')->generate();
|
return static::$kernel->getContainer()->get('nelmio_api_doc.generator')->generate();
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,34 @@ use Symfony\Component\Routing\RouteCollection;
|
|||||||
class FilteredRouteCollectionBuilderTest extends TestCase
|
class FilteredRouteCollectionBuilderTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testFilter()
|
public function testFilter()
|
||||||
|
{
|
||||||
|
$options = [
|
||||||
|
'path_patterns' => [
|
||||||
|
'^/api/foo',
|
||||||
|
'^/api/bar',
|
||||||
|
],
|
||||||
|
'host_patterns' => [
|
||||||
|
'^$',
|
||||||
|
'^api\.',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
foreach ($this->getRoutes() as $name => $route) {
|
||||||
|
$routes->add($name, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
$routeBuilder = new FilteredRouteCollectionBuilder($options);
|
||||||
|
$filteredRoutes = $routeBuilder->filter($routes);
|
||||||
|
|
||||||
|
$this->assertCount(4, $filteredRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @expectedDeprecation Passing an indexed array with a collection of path patterns as argument 1 for `Nelmio\ApiDocBundle\Routing\FilteredRouteCollectionBuilder::__construct()` is deprecated since 3.2.0, expected structure is an array containing parameterized options.
|
||||||
|
*/
|
||||||
|
public function testFilterWithDeprecatedArgument()
|
||||||
{
|
{
|
||||||
$pathPattern = [
|
$pathPattern = [
|
||||||
'^/api/foo',
|
'^/api/foo',
|
||||||
@ -29,15 +57,102 @@ class FilteredRouteCollectionBuilderTest extends TestCase
|
|||||||
];
|
];
|
||||||
|
|
||||||
$routes = new RouteCollection();
|
$routes = new RouteCollection();
|
||||||
$routes->add('r1', new Route('/api/bar/action1'));
|
foreach ($this->getRoutes() as $name => $route) {
|
||||||
$routes->add('r2', new Route('/api/foo/action1'));
|
$routes->add($name, $route);
|
||||||
$routes->add('r3', new Route('/api/foo/action2'));
|
}
|
||||||
$routes->add('r4', new Route('/api/demo'));
|
|
||||||
$routes->add('r5', new Route('/_profiler/test/test'));
|
|
||||||
|
|
||||||
$routeBuilder = new FilteredRouteCollectionBuilder($pathPattern);
|
$routeBuilder = new FilteredRouteCollectionBuilder($pathPattern);
|
||||||
$filteredRoutes = $routeBuilder->filter($routes);
|
$filteredRoutes = $routeBuilder->filter($routes);
|
||||||
|
|
||||||
$this->assertCount(3, $filteredRoutes);
|
$this->assertCount(5, $filteredRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @dataProvider getInvalidOptions
|
||||||
|
*/
|
||||||
|
public function testFilterWithInvalidOption(array $options)
|
||||||
|
{
|
||||||
|
new FilteredRouteCollectionBuilder($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInvalidOptions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['invalid_option' => null]],
|
||||||
|
[['invalid_option' => 42]],
|
||||||
|
[['invalid_option' => []]],
|
||||||
|
[['path_patterns' => [22]]],
|
||||||
|
[['path_patterns' => [null]]],
|
||||||
|
[['path_patterns' => [new \stdClass()]]],
|
||||||
|
[['path_patterns' => ['^/foo$', 1]]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRoutes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'r1' => new Route('/api/bar/action1'),
|
||||||
|
'r2' => new Route('/api/foo/action1'),
|
||||||
|
'r3' => new Route('/api/foo/action2'),
|
||||||
|
'r4' => new Route('/api/demo'),
|
||||||
|
'r5' => new Route('/_profiler/test/test'),
|
||||||
|
'r6' => new Route('/admin/bar/action1', [], [], [], 'www.example.com'),
|
||||||
|
'r7' => new Route('/api/bar/action1', [], [], [], 'www.example.com'),
|
||||||
|
'r8' => new Route('/admin/bar/action1', [], [], [], 'api.example.com'),
|
||||||
|
'r9' => new Route('/api/bar/action1', [], [], [], 'api.example.com'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getMatchingRoutes
|
||||||
|
*/
|
||||||
|
public function testMatchingRoutes(string $name, Route $route, array $options = [])
|
||||||
|
{
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
$routes->add($name, $route);
|
||||||
|
|
||||||
|
$routeBuilder = new FilteredRouteCollectionBuilder($options);
|
||||||
|
$filteredRoutes = $routeBuilder->filter($routes);
|
||||||
|
|
||||||
|
$this->assertCount(1, $filteredRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMatchingRoutes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['r1', new Route('/api/bar/action1')],
|
||||||
|
['r2', new Route('/api/foo/action1'), ['path_patterns' => ['^/api', 'i/fo', 'n1$']]],
|
||||||
|
['r3', new Route('/api/foo/action2'), ['path_patterns' => ['^/api/foo/action2$']]],
|
||||||
|
['r4', new Route('/api/demo'), ['path_patterns' => ['/api/demo']]],
|
||||||
|
['r9', new Route('/api/bar/action1', [], [], [], 'api.example.com'), ['path_patterns' => ['^/api/'], 'host_patterns' => ['^api\.ex']]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getNonMatchingRoutes
|
||||||
|
*/
|
||||||
|
public function testNonMatchingRoutes(string $name, Route $route, array $options = [])
|
||||||
|
{
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
$routes->add($name, $route);
|
||||||
|
|
||||||
|
$routeBuilder = new FilteredRouteCollectionBuilder($options);
|
||||||
|
$filteredRoutes = $routeBuilder->filter($routes);
|
||||||
|
|
||||||
|
$this->assertCount(0, $filteredRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNonMatchingRoutes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['r1', new Route('/api/bar/action1'), ['path_patterns' => ['^/apis']]],
|
||||||
|
['r2', new Route('/api/foo/action1'), ['path_patterns' => ['^/apis', 'i/foo/b', 'n1/$']]],
|
||||||
|
['r3_matching_path_and_non_matching_host', new Route('/api/foo/action2'), ['path_patterns' => ['^/api/foo/action2$'], 'host_patterns' => ['^api\.']]],
|
||||||
|
['r4_matching_path_and_non_matching_host', new Route('/api/bar/action1', [], [], [], 'www.example.com'), ['path_patterns' => ['^/api/'], 'host_patterns' => ['^api\.']]],
|
||||||
|
['r5_non_matching_path_and_matching_host', new Route('/admin/bar/action1', [], [], [], 'api.example.com'), ['path_patterns' => ['^/api/'], 'host_patterns' => ['^api\.']]],
|
||||||
|
['r6_non_matching_path_and_non_matching_host', new Route('/admin/bar/action1', [], [], [], 'www.example.com'), ['path_patterns' => ['^/api/'], 'host_patterns' => ['^api\.ex']]],
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^7.0",
|
"php": "^7.0",
|
||||||
"symfony/framework-bundle": "^3.4|^4.0",
|
"symfony/framework-bundle": "^3.4|^4.0",
|
||||||
|
"symfony/options-resolver": "^3.4.4|^4.0",
|
||||||
"symfony/property-info": "^3.4|^4.0",
|
"symfony/property-info": "^3.4|^4.0",
|
||||||
"exsyst/swagger": "~0.3|~0.4",
|
"exsyst/swagger": "~0.3|~0.4",
|
||||||
"zircote/swagger-php": "^2.0.9",
|
"zircote/swagger-php": "^2.0.9",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user