-
-
Notifications
You must be signed in to change notification settings - Fork 873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add page-based pagination to GraphQL #3175
Add page-based pagination to GraphQL #3175
Conversation
faf63b2
to
5493107
Compare
Nice feature! |
features/graphql/collection.feature
Outdated
collection { | ||
id | ||
} | ||
paginationMetadata { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
paginationInfo
to be coherent with the pageInfo
?
features/graphql/collection.feature
Outdated
""" | ||
Then the response status code should be 200 | ||
And the response should be in JSON | ||
And the JSON node "data.fooDummies.collection" should have 1 elements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the JSON node "data.fooDummies.collection" should have 1 elements | |
And the JSON node "data.fooDummies.collection" should have 1 element |
features/graphql/collection.feature
Outdated
And the JSON node "data.fooDummies.collection" should have 0 elements | ||
|
||
@createSchema | ||
Scenario: Retrieve a paginated collection using page-based pagination and client defined limit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scenario: Retrieve a paginated collection using page-based pagination and client defined limit | |
Scenario: Retrieve a paginated collection using page-based pagination and client-defined limit |
src/DataProvider/Pagination.php
Outdated
public function getGraphQlPaginationType(string $resourceClass = null, string $operationName = null): string | ||
{ | ||
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); | ||
|
||
return (string) $resourceMetadata->getGraphqlAttribute($operationName, 'paginationType', 'cursor', true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An if $resourceClass
or $operationName
is null
? Maybe they should not be nullable?
@@ -91,7 +93,10 @@ public function __invoke($itemOrCollection, string $resourceClass, string $opera | |||
$data[$index] = $this->normalizer->normalize($object, ItemNormalizer::FORMAT, $normalizationContext); | |||
} | |||
} else { | |||
$data = $this->serializePaginatedCollection($itemOrCollection, $normalizationContext, $context); | |||
$paginationType = $this->pagination->getGraphQlPaginationType($resourceClass, $operationName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like above, this variable is not needed.
$info = $context['info']; | ||
|
||
if (!($collection instanceof PaginatorInterface)) { | ||
throw Error::createLocatedError(sprintf('Collection returned by the collection data provider must implement %s', PaginatorInterface::class), $info->fieldNodes, $info->path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please throw a \LogicException
instead (see: https://github.com/api-platform/core/pull/3063/files).
src/GraphQl/Type/FieldsBuilder.php
Outdated
$args = [ | ||
'page' => [ | ||
'type' => GraphQLType::int(), | ||
'description' => 'The current page.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'description' => 'The current page.', | |
'description' => 'Returns the current page.', |
src/GraphQl/Type/FieldsBuilder.php
Outdated
if ($itemsPerPageOptions['client_items_per_page']) { | ||
$args[$itemsPerPageOptions['items_per_page_parameter_name']] = [ | ||
'type' => GraphQLType::int(), | ||
'description' => 'The number of items per page.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'description' => 'The number of items per page.', | |
'description' => 'Returns the number of items per page.', |
src/GraphQl/Type/FieldsBuilder.php
Outdated
'description' => 'Returns the elements in the list that come after the specified cursor.', | ||
], | ||
]; | ||
$paginationType = $this->pagination->getGraphQlPaginationType($resourceClass, $queryName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should introduce a private method here (like getFilterArgs
).
@raoulclais Any news on this? |
538e997
to
3acedd1
Compare
6820239
to
9609944
Compare
9609944
to
6653917
Compare
Thank you @raoulclais! 🙂 |
* Add page-based pagination to GraphQL * Use page_parameter_name Co-authored-by: Alan Poulain <contact@alanpoulain.eu>
@raoulclais @alanpoulain Hum, any object properties except "id" return a "null" value. If the property is nullable, it return null. If the property is not nullable it crash. The query:
With a not null but nullable property:
With a not null and not nullable property:
|
@jpierront you're right, I fixed it there: #3517. |
This PR allows to use a page-based pagination using GraphQL instead of the default cursor-based pagination. This choice is made at operation/resource level.