Skip to content

Commit 75a4855

Browse files
ragboyjrsoyuka
authored andcommitted
Expose Pagination in Swagger UI (api-platform#2171)
* Expose Pagination in Swagger UI fixes api-platform#2161 Signed-off-by: RJ Garcia <[email protected]> * Fix CS
1 parent fbd1bc1 commit 75a4855

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

src/Bridge/Symfony/Bundle/Resources/config/swagger.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
<argument>%api_platform.collection.pagination.page_parameter_name%</argument>
2929
<argument>%api_platform.collection.pagination.client_items_per_page%</argument>
3030
<argument>%api_platform.collection.pagination.items_per_page_parameter_name%</argument>
31+
<argument>%api_platform.collection.pagination.client_enabled%</argument>
32+
<argument>%api_platform.collection.pagination.enabled_parameter_name%</argument>
3133
<tag name="serializer.normalizer" priority="16" />
3234
</service>
3335

src/Swagger/Serializer/DocumentationNormalizer.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ final class DocumentationNormalizer implements NormalizerInterface, CacheableSup
6868
private $paginationPageParameterName;
6969
private $clientItemsPerPage;
7070
private $itemsPerPageParameterName;
71+
private $paginationClientEnabled;
72+
private $paginationClientEnabledParameterName;
7173

7274
/**
7375
* @param ContainerInterface|FilterCollection|null $filterLocator The new filter locator or the deprecated filter collection
7476
*/
75-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, OperationMethodResolverInterface $operationMethodResolver, OperationPathResolverInterface $operationPathResolver, UrlGeneratorInterface $urlGenerator = null, $filterLocator = null, NameConverterInterface $nameConverter = null, $oauthEnabled = false, $oauthType = '', $oauthFlow = '', $oauthTokenUrl = '', $oauthAuthorizationUrl = '', array $oauthScopes = [], array $apiKeys = [], SubresourceOperationFactoryInterface $subresourceOperationFactory = null, $paginationEnabled = true, $paginationPageParameterName = 'page', $clientItemsPerPage = false, $itemsPerPageParameterName = 'itemsPerPage')
77+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, OperationMethodResolverInterface $operationMethodResolver, OperationPathResolverInterface $operationPathResolver, UrlGeneratorInterface $urlGenerator = null, $filterLocator = null, NameConverterInterface $nameConverter = null, $oauthEnabled = false, $oauthType = '', $oauthFlow = '', $oauthTokenUrl = '', $oauthAuthorizationUrl = '', array $oauthScopes = [], array $apiKeys = [], SubresourceOperationFactoryInterface $subresourceOperationFactory = null, $paginationEnabled = true, $paginationPageParameterName = 'page', $clientItemsPerPage = false, $itemsPerPageParameterName = 'itemsPerPage', $paginationClientEnabled = false, $paginationClientEnabledParameterName = 'pagination')
7678
{
7779
if ($urlGenerator) {
7880
@trigger_error(sprintf('Passing an instance of %s to %s() is deprecated since version 2.1 and will be removed in 3.0.', UrlGeneratorInterface::class, __METHOD__), E_USER_DEPRECATED);
@@ -100,6 +102,8 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa
100102
$this->subresourceOperationFactory = $subresourceOperationFactory;
101103
$this->clientItemsPerPage = $clientItemsPerPage;
102104
$this->itemsPerPageParameterName = $itemsPerPageParameterName;
105+
$this->paginationClientEnabled = $paginationClientEnabled;
106+
$this->paginationClientEnabledParameterName = $paginationClientEnabledParameterName;
103107
}
104108

105109
/**
@@ -272,6 +276,9 @@ private function updateGetOperation(\ArrayObject $pathOperation, array $mimeType
272276
$pathOperation['parameters'][] = $this->getItemsPerPageParameters();
273277
}
274278
}
279+
if ($this->paginationEnabled && $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_client_enabled', $this->paginationClientEnabled, true)) {
280+
$pathOperation['parameters'][] = $this->getPaginationClientEnabledParameters();
281+
}
275282

276283
return $pathOperation;
277284
}
@@ -636,6 +643,20 @@ private function getPaginationParameters(): array
636643
];
637644
}
638645

646+
/**
647+
* Returns enable pagination parameter for the "get" collection operation.
648+
*/
649+
private function getPaginationClientEnabledParameters(): array
650+
{
651+
return [
652+
'name' => $this->paginationClientEnabledParameterName,
653+
'in' => 'query',
654+
'required' => false,
655+
'type' => 'boolean',
656+
'description' => 'Enable or disable pagination',
657+
];
658+
}
659+
639660
/**
640661
* Returns items per page parameters for the "get" collection operation.
641662
*/

tests/Swagger/Serializer/DocumentationNormalizerTest.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,4 +2000,103 @@ public function testNormalizeWithPropertySwaggerContext()
20002000

20012001
$this->assertEquals($expected, $normalizer->normalize($documentation, DocumentationNormalizer::FORMAT, ['base_url' => '/app_dev.php/']));
20022002
}
2003+
2004+
public function testNormalizeWithPaginationClientEnabled()
2005+
{
2006+
$documentation = new Documentation(new ResourceNameCollection([Dummy::class]), 'Test API', 'This is a test API.', '1.2.3', ['jsonld' => ['application/ld+json']]);
2007+
2008+
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
2009+
$propertyNameCollectionFactoryProphecy->create(Dummy::class, [])->shouldBeCalled()->willReturn(new PropertyNameCollection(['id', 'name']));
2010+
2011+
$dummyMetadata = new ResourceMetadata('Dummy', 'This is a dummy.', 'http://schema.example.com/Dummy', [], ['get' => ['method' => 'GET', 'pagination_client_enabled' => true]]);
2012+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
2013+
$resourceMetadataFactoryProphecy->create(Dummy::class)->shouldBeCalled()->willReturn($dummyMetadata);
2014+
2015+
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
2016+
$propertyMetadataFactoryProphecy->create(Dummy::class, 'id')->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_INT), 'This is an id.', true, false));
2017+
$propertyMetadataFactoryProphecy->create(Dummy::class, 'name')->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_STRING), 'This is a name.', true, true, true, true, false, false, null, null, ['swagger_context' => ['type' => 'string', 'enum' => ['one', 'two'], 'example' => 'one']]));
2018+
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
2019+
$resourceClassResolverProphecy->isResourceClass(Dummy::class)->willReturn(true);
2020+
2021+
$operationMethodResolverProphecy = $this->prophesize(OperationMethodResolverInterface::class);
2022+
$operationMethodResolverProphecy->getCollectionOperationMethod(Dummy::class, 'get')->shouldBeCalled()->willReturn('GET');
2023+
2024+
$operationPathResolver = new CustomOperationPathResolver(new OperationPathResolver(new UnderscorePathSegmentNameGenerator()));
2025+
2026+
$normalizer = new DocumentationNormalizer(
2027+
$resourceMetadataFactoryProphecy->reveal(),
2028+
$propertyNameCollectionFactoryProphecy->reveal(),
2029+
$propertyMetadataFactoryProphecy->reveal(),
2030+
$resourceClassResolverProphecy->reveal(),
2031+
$operationMethodResolverProphecy->reveal(),
2032+
$operationPathResolver
2033+
);
2034+
2035+
$expected = [
2036+
'swagger' => '2.0',
2037+
'basePath' => '/app_dev.php/',
2038+
'info' => [
2039+
'title' => 'Test API',
2040+
'description' => 'This is a test API.',
2041+
'version' => '1.2.3',
2042+
],
2043+
'paths' => new \ArrayObject([
2044+
'/dummies' => [
2045+
'get' => new \ArrayObject([
2046+
'tags' => ['Dummy'],
2047+
'operationId' => 'getDummyCollection',
2048+
'produces' => ['application/ld+json'],
2049+
'summary' => 'Retrieves the collection of Dummy resources.',
2050+
'parameters' => [
2051+
[
2052+
'name' => 'page',
2053+
'in' => 'query',
2054+
'required' => false,
2055+
'type' => 'integer',
2056+
'description' => 'The collection page number',
2057+
],
2058+
[
2059+
'name' => 'pagination',
2060+
'in' => 'query',
2061+
'required' => false,
2062+
'type' => 'boolean',
2063+
'description' => 'Enable or disable pagination',
2064+
],
2065+
],
2066+
'responses' => [
2067+
200 => [
2068+
'description' => 'Dummy collection response',
2069+
'schema' => [
2070+
'type' => 'array',
2071+
'items' => ['$ref' => '#/definitions/Dummy'],
2072+
],
2073+
],
2074+
],
2075+
]),
2076+
],
2077+
]),
2078+
'definitions' => new \ArrayObject([
2079+
'Dummy' => new \ArrayObject([
2080+
'type' => 'object',
2081+
'description' => 'This is a dummy.',
2082+
'externalDocs' => ['url' => 'http://schema.example.com/Dummy'],
2083+
'properties' => [
2084+
'id' => new \ArrayObject([
2085+
'type' => 'integer',
2086+
'description' => 'This is an id.',
2087+
'readOnly' => true,
2088+
]),
2089+
'name' => new \ArrayObject([
2090+
'type' => 'string',
2091+
'description' => 'This is a name.',
2092+
'enum' => ['one', 'two'],
2093+
'example' => 'one',
2094+
]),
2095+
],
2096+
]),
2097+
]),
2098+
];
2099+
2100+
$this->assertEquals($expected, $normalizer->normalize($documentation, DocumentationNormalizer::FORMAT, ['base_url' => '/app_dev.php/']));
2101+
}
20032102
}

0 commit comments

Comments
 (0)