core icon indicating copy to clipboard operation
core copied to clipboard

GraphQL skip count query if not necessary

Open jensstalder opened this issue 3 years ago • 0 comments

Description
Currently even if a query is being performed without specifying "totalCount" or "hasNextPage" the resolver will trigger a query by calling getTotalItems. This could be avoided automatically. This would avoid potentially expensive, non-scalable count queries from being performed for large collections. (or allow graphql to enable/disable partial pagination via request (just like the restful implementation with the partial_parameter_name paramteter)?)

Example

messages{
    totalCount
    edges {
        node {
            id
            title
        }
    }
}

Should cause SELECT count(DISTINCT since it is necessary.

messages{
    edges {
        node {
            id
            title
        }
    }
}

Should not cause count query since that information is never returned/requested.

Possible solution

ApiPlatform\Core\GraphQl\Resolver\Stage\SerializeStage::serializeCursorBasedPaginatedCollection() by updating the fragment:

/* ... */
if ($collection instanceof PaginatorInterface) {
    $fields = $context['info']->getFieldSelection(1);
     if (isset($fields['totalCount']) || isset($fields['pageInfo']['hasNextPage'])) {
        $totalItems = $collection->getTotalItems();    
     }
/* ... */

jensstalder avatar Apr 13 '22 15:04 jensstalder