How to Add Filtering, Sorting, and Pagination to Your Custom GraphQL in Magento 2

Create a Custom GraphQL Mutation in Magento2 (Step-by-Step Guide)

When building a custom GraphQL endpoint in Magento 2, basic data fetching is just the beginning. If you’re planning to build real-world APIs, especially for storefronts or dashboards, your custom GraphQL should support filtering, sorting, and pagination.

In this tutorial, we’ll walk you through how to enhance your custom GraphQL query to support these features in Magento 2 — all with clean and maintainable code.

Add Filtering, Sorting, and Pagination GraphQL in Magento 2

🧠 Why Filtering, Sorting, and Pagination Matter

When you’re building dynamic front-ends (like Vue/React apps or headless PWAs), you’ll likely need to:

  • Show a paginated list of items (e.g., 10 per page)
  • Let users search or filter records (e.g., by ID, name, etc.)
  • Sort the data (e.g., newest first, A–Z, etc.)

Magento 2’s GraphQL layer is powerful and flexible enough to support this natively — even in custom modules.

📦 Pre-requisites

Before starting, ensure you already have a custom GraphQL module set up. If you don’t, refer to our previous post:
👉 Create a Custom GraphQL Endpoint in Magento 2

Add Filtering, Sorting, and Pagination GraphQL in Magento 2

✅ Step 1: Define Your Schema

Update your schema.graphqls to include filter, sort, and pagination inputs:

type Query {
  getCustomRecords(
    filter: CustomRecordFilterInput
    sort: CustomRecordSortInput
    pageSize: Int = 10
    currentPage: Int = 1
  ): CustomRecordResult @resolver(class: "SbDevBlog\\CustomGraphQL\\Model\\Resolver\\GetRecords")
}

input CustomRecordFilterInput {
  id: IntFilterInput
  title: StringFilterInput
}

input CustomRecordSortInput {
  title: SortEnum
  id: SortEnum
}

enum SortEnum {
  ASC
  DESC
}

type CustomRecordResult {
  items: [CustomRecord]
  total_count: Int
  page_info: PageInfo!
}

type PageInfo {
  page_size: Int!
  current_page: Int!
  total_pages: Int!
}

🔧 Step 2: Update the Resolver Logic

Inside your resolver GetRecords.php, modify your code to apply filters, sorting, and pagination using Magento’s collection methods.


public function resolve(
    Field $field,
    $context,
    ResolveInfo $info,
    array $value = null,
    array $args = []
) {
    $collection = $this->collectionFactory->create();

    // Apply filters
    if (!empty($args['filter'])) {
        foreach ($args['filter'] as $field => $condition) {
            foreach ($condition as $type => $value) {
                $collection->addFieldToFilter($field, [$type => $value]);
            }
        }
    }

    // Apply sorting
    if (!empty($args['sort'])) {
        foreach ($args['sort'] as $field => $direction) {
            $collection->setOrder($field, $direction);
        }
    }

    // Pagination
    $pageSize = $args['pageSize'] ?? 10;
    $currentPage = $args['currentPage'] ?? 1;
    $collection->setPageSize($pageSize)->setCurPage($currentPage);

    // Format the response
    return [
        'items' => $collection->getItems(),
        'total_count' => $collection->getSize(),
        'page_info' => [
            'page_size' => $pageSize,
            'current_page' => $currentPage,
            'total_pages' => ceil($collection->getSize() / $pageSize)
        ]
    ];
}

🧪 Test Example Query

query {
  getCustomRecords(
    filter: { title: { like: "%demo%" } }
    sort: { id: DESC }
    pageSize: 5
    currentPage: 1
  ) {
    items {
      id
      title
      description
    }
    total_count
    page_info {
      page_size
      current_page
      total_pages
    }
  }
}

This will return filtered records where the title includes “demo”, sorted by ID in descending order, and paginated to 5 items per page.

🛠️ Pro Tips

  • Use like, eq, neq, in, and gt/lt for rich filtering.
  • Combine multiple filters for advanced querying.
  • Keep resolver logic clean by offloading filtering/sorting to a service class if it grows large.

📘 Wrapping Up – Add Filtering, Sorting, and Pagination GraphQL in Magento 2

You’ve now empowered your custom GraphQL endpoint with all the tools it needs to behave like a production-ready API. Filtering, sorting, and pagination are must-haves for scalable, performant APIs — and Magento 2 makes it pretty smooth once you understand the pattern.


✨ Next Post Preview

In the next guide, we’ll dive into creating GraphQL mutations to insert, update, and delete data in your custom table — making your Magento GraphQL truly full-stack.

🔗 Stay tuned on SB Dev Blog for more Magento magic!

Leave a Reply

Your email address will not be published. Required fields are marked *