diff --git a/CHANGELOG.md b/CHANGELOG.md
index 37edc3d9d22..40c3f92020a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* GraphQL: Add support for custom queries and mutations
* GraphQL: Add support for custom types
* GraphQL: Better pagination support (backwards pagination)
+* GraphQL: Support the pagination per resource
* GraphQL: Add the concept of *stages* in the workflow of the resolvers and add the possibility to disable them with operation attributes
* GraphQL: Add GraphQL Playground besides GraphiQL and add the possibility to change the default IDE (or to disable it) for the GraphQL endpoint
* GraphQL: Add a command to print the schema in SDL
diff --git a/features/graphql/collection.feature b/features/graphql/collection.feature
index 894347550f5..f26132582dd 100644
--- a/features/graphql/collection.feature
+++ b/features/graphql/collection.feature
@@ -482,6 +482,26 @@ Feature: GraphQL collection support
And the header "Content-Type" should be equal to "application/json"
And the JSON node "data.dummies.edges" should have 0 element
+ @createSchema
+ Scenario: Retrieve a collection with pagination disabled
+ Given there are 4 foo objects with fake names
+ When I send the following GraphQL request:
+ """
+ {
+ foos {
+ id
+ name
+ bar
+ }
+ }
+ """
+ Then the response status code should be 200
+ And the response should be in JSON
+ And the header "Content-Type" should be equal to "application/json"
+ And the JSON node "data.foos[3].id" should be equal to "/foos/4"
+ And the JSON node "data.foos[3].name" should be equal to "Separativeness"
+ And the JSON node "data.foos[3].bar" should be equal to "Sit"
+
Scenario: Custom collection query
Given there are 2 dummyCustomQuery objects
When I send the following GraphQL request:
diff --git a/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php b/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php
index 4b0a9da8475..75215bbeb61 100644
--- a/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php
+++ b/src/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php
@@ -52,6 +52,10 @@ public function applyToCollection(Builder $aggregationBuilder, string $resourceC
return;
}
+ if (($context['graphql_operation_name'] ?? false) && !$this->pagination->isGraphQlEnabled($resourceClass, $operationName, $context)) {
+ return;
+ }
+
$context = $this->addCountToContext(clone $aggregationBuilder, $context);
[, $offset, $limit] = $this->pagination->getPagination($resourceClass, $operationName, $context);
@@ -90,6 +94,10 @@ public function applyToCollection(Builder $aggregationBuilder, string $resourceC
*/
public function supportsResult(string $resourceClass, string $operationName = null, array $context = []): bool
{
+ if ($context['graphql_operation_name'] ?? false) {
+ return $this->pagination->isGraphQlEnabled($resourceClass, $operationName, $context);
+ }
+
return $this->pagination->isEnabled($resourceClass, $operationName, $context);
}
diff --git a/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php b/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php
index 64e3f294fb2..d1e6a48e4ff 100644
--- a/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php
+++ b/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php
@@ -134,6 +134,10 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator
*/
public function supportsResult(string $resourceClass, string $operationName = null, array $context = []): bool
{
+ if ($context['graphql_operation_name'] ?? false) {
+ return $this->pagination->isGraphQlEnabled($resourceClass, $operationName, $context);
+ }
+
if (null === $this->requestStack) {
return $this->pagination->isEnabled($resourceClass, $operationName, $context);
}
@@ -193,6 +197,10 @@ private function getPagination(QueryBuilder $queryBuilder, string $resourceClass
return null;
}
+ if (($context['graphql_operation_name'] ?? false) && !$this->pagination->isGraphQlEnabled($resourceClass, $operationName, $context)) {
+ return null;
+ }
+
$context = $this->addCountToContext($queryBuilder, $context);
return \array_slice($this->pagination->getPagination($resourceClass, $operationName, $context), 1);
diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
index ccbf91515a8..886628944df 100644
--- a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
+++ b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
@@ -378,6 +378,7 @@ private function registerGraphQlConfiguration(ContainerBuilder $container, array
}
$container->setParameter('api_platform.graphql.default_ide', $config['graphql']['default_ide']);
+ $container->setParameter('api_platform.graphql.collection.pagination', $config['graphql']['collection']['pagination']);
$loader->load('graphql.xml');
diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
index 7ab0c5da92e..40e43a3eee6 100644
--- a/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
+++ b/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
@@ -239,6 +239,14 @@ private function addGraphQlSection(ArrayNodeDefinition $rootNode): void
->arrayNode('graphql_playground')
->{class_exists(GraphQL::class) && class_exists(TwigBundle::class) ? 'canBeDisabled' : 'canBeEnabled'}()
->end()
+ ->arrayNode('collection')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->arrayNode('pagination')
+ ->canBeDisabled()
+ ->end()
+ ->end()
+ ->end()
->end()
->end()
->end();
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/data_provider.xml b/src/Bridge/Symfony/Bundle/Resources/config/data_provider.xml
index a64b76fe370..800cdaf4511 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/data_provider.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/data_provider.xml
@@ -30,6 +30,7 @@
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/graphql.xml b/src/Bridge/Symfony/Bundle/Resources/config/graphql.xml
index 5a3a78f8ce5..147b0af5cda 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/graphql.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/graphql.xml
@@ -64,7 +64,7 @@
- %api_platform.collection.pagination.enabled%
+
@@ -135,7 +135,7 @@
- %api_platform.collection.pagination.enabled%
+
diff --git a/src/DataProvider/Pagination.php b/src/DataProvider/Pagination.php
index 4b912e2133d..9326ad9fcb9 100644
--- a/src/DataProvider/Pagination.php
+++ b/src/DataProvider/Pagination.php
@@ -14,6 +14,7 @@
namespace ApiPlatform\Core\DataProvider;
use ApiPlatform\Core\Exception\InvalidArgumentException;
+use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
/**
@@ -24,9 +25,10 @@
final class Pagination
{
private $options;
+ private $graphQlOptions;
private $resourceMetadataFactory;
- public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, array $options = [])
+ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, array $options = [], array $graphQlOptions = [])
{
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->options = array_merge([
@@ -43,6 +45,9 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa
'client_partial' => false,
'partial_parameter_name' => 'partial',
], $options);
+ $this->graphQlOptions = array_merge([
+ 'enabled' => true,
+ ], $graphQlOptions);
}
/**
@@ -171,6 +176,14 @@ public function isEnabled(string $resourceClass = null, string $operationName =
return $this->getEnabled($context, $resourceClass, $operationName);
}
+ /**
+ * Is the pagination enabled for GraphQL?
+ */
+ public function isGraphQlEnabled(?string $resourceClass = null, ?string $operationName = null, array $context = []): bool
+ {
+ return $this->getGraphQlEnabled($resourceClass, $operationName);
+ }
+
/**
* Is the partial pagination enabled?
*/
@@ -198,6 +211,23 @@ private function getEnabled(array $context, string $resourceClass = null, string
return filter_var($this->getParameterFromContext($context, $this->options[$partial ? 'partial_parameter_name' : 'enabled_parameter_name'], $enabled), FILTER_VALIDATE_BOOLEAN);
}
+ return (bool) $enabled;
+ }
+
+ private function getGraphQlEnabled(?string $resourceClass, ?string $operationName): bool
+ {
+ $enabled = $this->graphQlOptions['enabled'];
+
+ if (null !== $resourceClass) {
+ try {
+ $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
+ } catch (ResourceClassNotFoundException $e) {
+ return $enabled;
+ }
+
+ return (bool) $resourceMetadata->getGraphqlAttribute($operationName, 'pagination_enabled', $enabled, true);
+ }
+
return $enabled;
}
diff --git a/src/GraphQl/Resolver/Factory/ItemResolverFactory.php b/src/GraphQl/Resolver/Factory/ItemResolverFactory.php
index 5931747d712..ed00054e537 100644
--- a/src/GraphQl/Resolver/Factory/ItemResolverFactory.php
+++ b/src/GraphQl/Resolver/Factory/ItemResolverFactory.php
@@ -79,7 +79,7 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
if (null !== $queryResolverId) {
/** @var QueryItemResolverInterface $queryResolver */
$queryResolver = $this->queryResolverLocator->get($queryResolverId);
- $item = $queryResolver($item, ['source' => $source, 'args' => $args, 'info' => $info]);
+ $item = $queryResolver($item, $resolverContext);
$resourceClass = $this->getResourceClass($item, $resourceClass, $info, sprintf('Custom query resolver "%s"', $queryResolverId).' has to return an item of class %s but returned an item of class %s.');
}
diff --git a/src/GraphQl/Resolver/Stage/ReadStage.php b/src/GraphQl/Resolver/Stage/ReadStage.php
index 522c46f9344..6a57d9dda30 100644
--- a/src/GraphQl/Resolver/Stage/ReadStage.php
+++ b/src/GraphQl/Resolver/Stage/ReadStage.php
@@ -92,7 +92,7 @@ public function __invoke(?string $resourceClass, ?string $rootClass, string $ope
$source = $context['source'];
if (isset($source[$rootProperty = $info->fieldName], $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY])) {
$rootResolvedFields = $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY];
- $subresourceCollection = $this->getSubresource($rootClass, $rootResolvedFields, $rootProperty, $resourceClass, $normalizationContext);
+ $subresourceCollection = $this->getSubresource($rootClass, $rootResolvedFields, $rootProperty, $resourceClass, $normalizationContext, $operationName);
if (!is_iterable($subresourceCollection)) {
throw new \UnexpectedValueException('Expected subresource collection to be iterable');
}
@@ -100,7 +100,7 @@ public function __invoke(?string $resourceClass, ?string $rootClass, string $ope
return $subresourceCollection;
}
- return $this->collectionDataProvider->getCollection($resourceClass, null, $normalizationContext);
+ return $this->collectionDataProvider->getCollection($resourceClass, $operationName, $normalizationContext);
}
private function getIdentifier(array $context): ?string
@@ -156,7 +156,7 @@ private function getNormalizedFilters(array $args): array
/**
* @return iterable|object|null
*/
- private function getSubresource(string $rootClass, array $rootResolvedFields, string $rootProperty, string $subresourceClass, array $normalizationContext)
+ private function getSubresource(string $rootClass, array $rootResolvedFields, string $rootProperty, string $subresourceClass, array $normalizationContext, string $operationName)
{
$resolvedIdentifiers = [];
$rootIdentifiers = array_keys($rootResolvedFields);
@@ -168,6 +168,6 @@ private function getSubresource(string $rootClass, array $rootResolvedFields, st
'property' => $rootProperty,
'identifiers' => $resolvedIdentifiers,
'collection' => true,
- ]);
+ ], $operationName);
}
}
diff --git a/src/GraphQl/Resolver/Stage/SerializeStage.php b/src/GraphQl/Resolver/Stage/SerializeStage.php
index 57715d63fe2..8c1d6feff07 100644
--- a/src/GraphQl/Resolver/Stage/SerializeStage.php
+++ b/src/GraphQl/Resolver/Stage/SerializeStage.php
@@ -13,6 +13,7 @@
namespace ApiPlatform\Core\GraphQl\Resolver\Stage;
+use ApiPlatform\Core\DataProvider\Pagination;
use ApiPlatform\Core\DataProvider\PaginatorInterface;
use ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer;
use ApiPlatform\Core\GraphQl\Serializer\SerializerContextBuilderInterface;
@@ -33,14 +34,14 @@ final class SerializeStage implements SerializeStageInterface
private $resourceMetadataFactory;
private $normalizer;
private $serializerContextBuilder;
- private $paginationEnabled;
+ private $pagination;
- public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, NormalizerInterface $normalizer, SerializerContextBuilderInterface $serializerContextBuilder, bool $paginationEnabled)
+ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, NormalizerInterface $normalizer, SerializerContextBuilderInterface $serializerContextBuilder, Pagination $pagination)
{
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->normalizer = $normalizer;
$this->serializerContextBuilder = $serializerContextBuilder;
- $this->paginationEnabled = $paginationEnabled;
+ $this->pagination = $pagination;
}
/**
@@ -54,7 +55,7 @@ public function __invoke($itemOrCollection, string $resourceClass, string $opera
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
if (!$resourceMetadata->getGraphqlAttribute($operationName, 'serialize', true, true)) {
if ($isCollection) {
- if ($this->paginationEnabled) {
+ if ($this->pagination->isGraphQlEnabled($resourceClass, $operationName, $context)) {
return $this->getDefaultPaginatedData();
}
@@ -84,7 +85,7 @@ public function __invoke($itemOrCollection, string $resourceClass, string $opera
}
if ($isCollection && is_iterable($itemOrCollection)) {
- if (!$this->paginationEnabled) {
+ if (!$this->pagination->isGraphQlEnabled($resourceClass, $operationName, $context)) {
$data = [];
foreach ($itemOrCollection as $index => $object) {
$data[$index] = $this->normalizer->normalize($object, ItemNormalizer::FORMAT, $normalizationContext);
diff --git a/src/GraphQl/Type/FieldsBuilder.php b/src/GraphQl/Type/FieldsBuilder.php
index 87a295762fa..42c9c343798 100644
--- a/src/GraphQl/Type/FieldsBuilder.php
+++ b/src/GraphQl/Type/FieldsBuilder.php
@@ -13,6 +13,7 @@
namespace ApiPlatform\Core\GraphQl\Type;
+use ApiPlatform\Core\DataProvider\Pagination;
use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
use ApiPlatform\Core\GraphQl\Resolver\Factory\ResolverFactoryInterface;
use ApiPlatform\Core\GraphQl\Type\Definition\TypeInterface;
@@ -48,9 +49,9 @@ final class FieldsBuilder implements FieldsBuilderInterface
private $collectionResolverFactory;
private $itemMutationResolverFactory;
private $filterLocator;
- private $paginationEnabled;
+ private $pagination;
- public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, TypesContainerInterface $typesContainer, TypeBuilderInterface $typeBuilder, TypeConverterInterface $typeConverter, ResolverFactoryInterface $itemResolverFactory, ResolverFactoryInterface $collectionResolverFactory, ResolverFactoryInterface $itemMutationResolverFactory, ContainerInterface $filterLocator, bool $paginationEnabled)
+ public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, TypesContainerInterface $typesContainer, TypeBuilderInterface $typeBuilder, TypeConverterInterface $typeConverter, ResolverFactoryInterface $itemResolverFactory, ResolverFactoryInterface $collectionResolverFactory, ResolverFactoryInterface $itemMutationResolverFactory, ContainerInterface $filterLocator, Pagination $pagination)
{
$this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
$this->propertyMetadataFactory = $propertyMetadataFactory;
@@ -62,7 +63,7 @@ public function __construct(PropertyNameCollectionFactoryInterface $propertyName
$this->collectionResolverFactory = $collectionResolverFactory;
$this->itemMutationResolverFactory = $itemMutationResolverFactory;
$this->filterLocator = $filterLocator;
- $this->paginationEnabled = $paginationEnabled;
+ $this->pagination = $pagination;
}
/**
@@ -247,7 +248,7 @@ private function getResourceFieldConfiguration(?string $property, ?string $field
$args = [];
if (!$input && null === $mutationName && !$isStandardGraphqlType && $this->typeBuilder->isCollection($type)) {
- if ($this->paginationEnabled) {
+ if ($this->pagination->isGraphQlEnabled($resourceClass, $queryName)) {
$args = [
'first' => [
'type' => GraphQLType::int(),
@@ -409,7 +410,7 @@ private function convertType(Type $type, bool $input, ?string $queryName, ?strin
}
if ($this->typeBuilder->isCollection($type)) {
- return $this->paginationEnabled && !$input ? $this->typeBuilder->getResourcePaginatedCollectionType($graphqlType) : GraphQLType::listOf($graphqlType);
+ return $this->pagination->isGraphQlEnabled($resourceClass, $queryName ?? $mutationName) && !$input ? $this->typeBuilder->getResourcePaginatedCollectionType($graphqlType) : GraphQLType::listOf($graphqlType);
}
return !$graphqlType instanceof NullableType || $type->isNullable() || (null !== $mutationName && 'update' === $mutationName)
diff --git a/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php b/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php
index bae73dd4244..a4c7e4837d9 100644
--- a/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php
+++ b/tests/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtensionTest.php
@@ -290,6 +290,28 @@ public function testApplyToCollectionPaginationDisabled()
$extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context);
}
+ public function testApplyToCollectionGraphQlPaginationDisabled()
+ {
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []));
+ $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
+
+ $pagination = new Pagination($resourceMetadataFactory, [], [
+ 'enabled' => false,
+ ]);
+
+ $aggregationBuilderProphecy = $this->prophesize(Builder::class);
+ $aggregationBuilderProphecy->facet()->shouldNotBeCalled();
+
+ $context = ['graphql_operation_name' => 'op'];
+
+ $extension = new PaginationExtension(
+ $this->managerRegistryProphecy->reveal(),
+ $pagination
+ );
+ $extension->applyToCollection($aggregationBuilderProphecy->reveal(), 'Foo', 'op', $context);
+ }
+
public function testApplyToCollectionWithMaximumItemsPerPage()
{
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
@@ -368,6 +390,23 @@ public function testSupportsResultPaginationDisabled()
$this->assertFalse($extension->supportsResult('Foo', 'op', ['filters' => ['enabled' => false]]));
}
+ public function testSupportsResultGraphQlPaginationDisabled()
+ {
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []));
+ $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
+
+ $pagination = new Pagination($resourceMetadataFactory, [], [
+ 'enabled' => false,
+ ]);
+
+ $extension = new PaginationExtension(
+ $this->managerRegistryProphecy->reveal(),
+ $pagination
+ );
+ $this->assertFalse($extension->supportsResult('Foo', 'op', ['filters' => ['enabled' => false], 'graphql_operation_name' => 'op']));
+ }
+
public function testGetResult()
{
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
diff --git a/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php b/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php
index 64e56e4dc79..0b7e05949db 100644
--- a/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php
+++ b/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php
@@ -651,6 +651,29 @@ public function testLegacyApplyToCollectionPaginationDisabled()
$extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op');
}
+ public function testApplyToCollectionGraphQlPaginationDisabled()
+ {
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []));
+ $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
+
+ $pagination = new Pagination($resourceMetadataFactory, [], [
+ 'enabled' => false,
+ ]);
+
+ $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
+ $queryBuilderProphecy->setFirstResult(Argument::any())->shouldNotBeCalled();
+ $queryBuilderProphecy->setMaxResults(Argument::any())->shouldNotBeCalled();
+ $queryBuilder = $queryBuilderProphecy->reveal();
+
+ $extension = new PaginationExtension(
+ $this->prophesize(ManagerRegistry::class)->reveal(),
+ $resourceMetadataFactory,
+ $pagination
+ );
+ $extension->applyToCollection($queryBuilder, new QueryNameGenerator(), 'Foo', 'op', ['graphql_operation_name' => 'op']);
+ }
+
public function testApplyToCollectionWithMaximumItemsPerPage()
{
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
@@ -883,6 +906,24 @@ public function testLegacySupportsResultPaginationDisabled()
$this->assertFalse($extension->supportsResult('Foo', 'op'));
}
+ public function testSupportsResultGraphQlPaginationDisabled()
+ {
+ $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $resourceMetadataFactoryProphecy->create('Foo')->willReturn(new ResourceMetadata(null, null, null, [], []));
+ $resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
+
+ $pagination = new Pagination($resourceMetadataFactory, [], [
+ 'enabled' => false,
+ ]);
+
+ $extension = new PaginationExtension(
+ $this->prophesize(ManagerRegistry::class)->reveal(),
+ $resourceMetadataFactory,
+ $pagination
+ );
+ $this->assertFalse($extension->supportsResult('Foo', 'op', ['graphql_operation_name' => 'op']));
+ }
+
public function testGetResult()
{
$dummyMetadata = new ClassMetadata(Dummy::class);
diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php
index 87d3de7c536..bc68efb031a 100644
--- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php
+++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php
@@ -366,6 +366,8 @@ public function testDisableGraphQl()
$containerBuilderProphecy->setParameter('api_platform.graphql.enabled', false)->shouldBeCalled();
$containerBuilderProphecy->setParameter('api_platform.graphql.default_ide', 'graphiql')->shouldNotBeCalled();
$containerBuilderProphecy->setParameter('api_platform.graphql.default_ide', Argument::any())->shouldNotBeCalled();
+ $containerBuilderProphecy->setParameter('api_platform.graphql.collection.pagination', ['enabled' => true])->shouldNotBeCalled();
+ $containerBuilderProphecy->setParameter('api_platform.graphql.collection.pagination', Argument::any())->shouldNotBeCalled();
$containerBuilderProphecy->setParameter('api_platform.graphql.graphiql.enabled', true)->shouldNotBeCalled();
$containerBuilderProphecy->setParameter('api_platform.graphql.graphiql.enabled', false)->shouldBeCalled();
$containerBuilderProphecy->setParameter('api_platform.graphql.graphql_playground.enabled', true)->shouldNotBeCalled();
@@ -1060,6 +1062,7 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo
'api_platform.enable_re_doc' => true,
'api_platform.graphql.enabled' => true,
'api_platform.graphql.default_ide' => 'graphiql',
+ 'api_platform.graphql.collection.pagination' => ['enabled' => true],
'api_platform.graphql.graphiql.enabled' => true,
'api_platform.graphql.graphql_playground.enabled' => true,
'api_platform.resource_class_directories' => Argument::type('array'),
diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php
index c631b7b1fe9..e7bff85edb5 100644
--- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php
+++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php
@@ -124,6 +124,11 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
'graphiql' => [
'enabled' => true,
],
+ 'collection' => [
+ 'pagination' => [
+ 'enabled' => true,
+ ],
+ ],
],
'elasticsearch' => [
'enabled' => false,
diff --git a/tests/Fixtures/TestBundle/Document/Foo.php b/tests/Fixtures/TestBundle/Document/Foo.php
index 6bbeb6a544b..d159b9362bb 100644
--- a/tests/Fixtures/TestBundle/Document/Foo.php
+++ b/tests/Fixtures/TestBundle/Document/Foo.php
@@ -21,9 +21,17 @@
*
* @author Vincent Chalamon
*
- * @ApiResource(attributes={
- * "order"={"bar", "name"="DESC"}
- * })
+ * @ApiResource(
+ * attributes={
+ * "order"={"bar", "name"="DESC"}
+ * },
+ * graphql={
+ * "item_query",
+ * "collection_query"={"pagination_enabled"=false},
+ * "create",
+ * "delete"
+ * }
+ * )
* @ODM\Document
*/
class Foo
diff --git a/tests/Fixtures/TestBundle/Entity/Foo.php b/tests/Fixtures/TestBundle/Entity/Foo.php
index 3b0115ec18c..dd970d4f639 100644
--- a/tests/Fixtures/TestBundle/Entity/Foo.php
+++ b/tests/Fixtures/TestBundle/Entity/Foo.php
@@ -21,9 +21,17 @@
*
* @author Vincent Chalamon
*
- * @ApiResource(attributes={
- * "order"={"bar", "name"="DESC"}
- * })
+ * @ApiResource(
+ * attributes={
+ * "order"={"bar", "name"="DESC"}
+ * },
+ * graphql={
+ * "item_query",
+ * "collection_query"={"pagination_enabled"=false},
+ * "create",
+ * "delete"
+ * }
+ * )
* @ORM\Entity
*/
class Foo
diff --git a/tests/GraphQl/Resolver/Stage/ReadStageTest.php b/tests/GraphQl/Resolver/Stage/ReadStageTest.php
index 2430ef7f52a..754f75e9393 100644
--- a/tests/GraphQl/Resolver/Stage/ReadStageTest.php
+++ b/tests/GraphQl/Resolver/Stage/ReadStageTest.php
@@ -201,9 +201,9 @@ public function testApplyCollection(array $args, ?string $rootClass, ?array $sou
$normalizationContext = ['normalization' => true];
$this->serializerContextBuilderProphecy->create($resourceClass, $operationName, $context, true)->shouldBeCalled()->willReturn($normalizationContext);
- $this->subresourceDataProviderProphecy->getSubresource($resourceClass, ['id' => 3], $normalizationContext + ['filters' => $expectedFilters, 'property' => $fieldName, 'identifiers' => [['id', $resourceClass]], 'collection' => true])->willReturn(['subresource']);
+ $this->subresourceDataProviderProphecy->getSubresource($resourceClass, ['id' => 3], $normalizationContext + ['filters' => $expectedFilters, 'property' => $fieldName, 'identifiers' => [['id', $resourceClass]], 'collection' => true], $operationName)->willReturn(['subresource']);
- $this->collectionDataProviderProphecy->getCollection($resourceClass, null, $normalizationContext + ['filters' => $expectedFilters])->willReturn($expectedResult);
+ $this->collectionDataProviderProphecy->getCollection($resourceClass, $operationName, $normalizationContext + ['filters' => $expectedFilters])->willReturn($expectedResult);
$result = ($this->readStage)($resourceClass, $rootClass, $operationName, $context);
diff --git a/tests/GraphQl/Resolver/Stage/SerializeStageTest.php b/tests/GraphQl/Resolver/Stage/SerializeStageTest.php
index 7e9ce67cf92..640d15cfa90 100644
--- a/tests/GraphQl/Resolver/Stage/SerializeStageTest.php
+++ b/tests/GraphQl/Resolver/Stage/SerializeStageTest.php
@@ -14,6 +14,7 @@
namespace ApiPlatform\Core\Tests\GraphQl\Resolver\Stage;
use ApiPlatform\Core\DataProvider\ArrayPaginator;
+use ApiPlatform\Core\DataProvider\Pagination;
use ApiPlatform\Core\GraphQl\Resolver\Stage\SerializeStage;
use ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer;
use ApiPlatform\Core\GraphQl\Serializer\SerializerContextBuilderInterface;
@@ -170,11 +171,13 @@ public function testApplyBadNormalizedData(): void
private function createSerializeStage(bool $paginationEnabled): SerializeStage
{
+ $pagination = new Pagination($this->resourceMetadataFactoryProphecy->reveal(), [], ['enabled' => $paginationEnabled]);
+
return new SerializeStage(
$this->resourceMetadataFactoryProphecy->reveal(),
$this->normalizerProphecy->reveal(),
$this->serializerContextBuilderProphecy->reveal(),
- $paginationEnabled
+ $pagination
);
}
}
diff --git a/tests/GraphQl/Type/FieldsBuilderTest.php b/tests/GraphQl/Type/FieldsBuilderTest.php
index c766967e87a..2deb9703417 100644
--- a/tests/GraphQl/Type/FieldsBuilderTest.php
+++ b/tests/GraphQl/Type/FieldsBuilderTest.php
@@ -14,6 +14,7 @@
namespace ApiPlatform\Core\Tests\GraphQl\Type;
use ApiPlatform\Core\Api\FilterInterface;
+use ApiPlatform\Core\DataProvider\Pagination;
use ApiPlatform\Core\GraphQl\Resolver\Factory\ResolverFactoryInterface;
use ApiPlatform\Core\GraphQl\Type\FieldsBuilder;
use ApiPlatform\Core\GraphQl\Type\TypeBuilderInterface;
@@ -90,7 +91,7 @@ protected function setUp(): void
$this->collectionResolverFactoryProphecy = $this->prophesize(ResolverFactoryInterface::class);
$this->itemMutationResolverFactoryProphecy = $this->prophesize(ResolverFactoryInterface::class);
$this->filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
- $this->fieldsBuilder = new FieldsBuilder($this->propertyNameCollectionFactoryProphecy->reveal(), $this->propertyMetadataFactoryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $this->typesContainerProphecy->reveal(), $this->typeBuilderProphecy->reveal(), $this->typeConverterProphecy->reveal(), $this->itemResolverFactoryProphecy->reveal(), $this->collectionResolverFactoryProphecy->reveal(), $this->itemMutationResolverFactoryProphecy->reveal(), $this->filterLocatorProphecy->reveal(), true);
+ $this->fieldsBuilder = new FieldsBuilder($this->propertyNameCollectionFactoryProphecy->reveal(), $this->propertyMetadataFactoryProphecy->reveal(), $this->resourceMetadataFactoryProphecy->reveal(), $this->typesContainerProphecy->reveal(), $this->typeBuilderProphecy->reveal(), $this->typeConverterProphecy->reveal(), $this->itemResolverFactoryProphecy->reveal(), $this->collectionResolverFactoryProphecy->reveal(), $this->itemMutationResolverFactoryProphecy->reveal(), $this->filterLocatorProphecy->reveal(), new Pagination($this->resourceMetadataFactoryProphecy->reveal()));
}
public function testGetNodeQueryFields(): void