Magento 2 Get Product Collection Using GraphQL

In Magento 2, if you want to get all the product collection using GraphQL, you can do it just by creating a simple module.

We need to create a resolver model where we will write our custom logic to retrieve all the product collection.

First, we need to create registration.php and module.xml to define our module registration.

Path: app/code/Magemeta/ProductCollectionGraphQl/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Magemeta_ProductCollectionGraphQl',
    __DIR__
);

Create module.xml file, Path: app/code/Magemeta/ProductsGraphQl/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Magemeta_ProductCollectionGraphQl">
        <sequence>
            <module name="Magento_Catalog"/>
            <module name="Magento_GraphQl"/>
        </sequence>
    </module>
</config>

We need to declare the GraphQL and Catalog module dependency in the module.xml file.

Every GraphQL module must contain schema.graphqls file in the etc folder of a module.

schema.graphqls explains our GraphQL Query implementation and describes what data can be queried in the query. So we can define our query data format in the schema.graphqls file.

Path: app/code/Magemeta/ProductCollectionGraphQl/etc/schema.graphqls

type Query {
    productCollection: ProductCollection @resolver(class: "Magemeta\\ProductCollectionGraphQl\\Model\\Resolver\\ProductsResolver") @doc(description: "Get product collection of a store")
}
 
type ProductCollection @doc(description: "Product collection details") {
    allProducts: [ProductRecord] @doc(description: "Product items with details")
}
 
type ProductRecord {
    sku: String @doc(description: "Get product sku")
    name: String @doc(description: "Get product name")
    price: Float @doc(description: "Get product price")
}

Next, we have to create a resolver model for our custom module on path as  Magemeta\\ProductCollectionGraphQl\\Model\\Resolver\\ProductsResolver
which is defined in the schema.graphql file.

The resolve() method of model will return collection data of all the products. We only display product SKU, name, and price from products. You can add the extra field to display in the response of the query by adding the extra parameter in the schema.graphql file.

Path: app/code/Magemeta/ProductCollectionGraphQl/Model/Resolver/ProductsResolver.php

<?php
declare(strict_types=1);
 
namespace Magemeta\ProductCollectionGraphQl\Model\Resolver;
 
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
 
/**
 * Product collection resolver
 */
class ProductsResolver implements ResolverInterface
{
    public function __construct(
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
    ) {
        $this->productRepository = $productRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
    }
 
    /**
     * @inheritdoc
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        $productsData = $this->getProductsData();
        return $productsData;
    }
 
    /**
     * @return array
     * @throws GraphQlNoSuchEntityException
     */
    private function getProductsData(): array
    {
        try {
            /* filter for all the pages */
            $searchCriteria = $this->searchCriteriaBuilder->addFilter('entity_id', 1,'gteq')->create();
            $products = $this->productRepository->getList($searchCriteria)->getItems();
            $productItems['allProducts'] = [];
            $productId = $product->getId();
            foreach($products as $product) {
                $productItems['allProducts'][$productId]['sku'] = $product->getSku();
                $productItems['allProducts'][$productId]['name'] = $product->getName();
                $productItems['allProducts'][$productId]['price'] = $product->getPrice();
            }
        } catch (NoSuchEntityException $e) {
            throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
        }
        return $productItems;
    }
}

Next we need to run the setup:upgrade command to install our custom module.

php bin/magento setup:upgrade
php bin/magento cache:flush

We can check your GraphQL query response by installing chrome extension ChromeiQL or Altair GraphQL addon via Browser.

Request Payload:

{
  productCollection {
    allProducts {
      sku
      name
      price
    }
  }
}

Result:

{
  "data": {
    "productCollection": {
      "allProducts": [
        {
          "sku": "Test Product 1",
          "name": "Test Product 1",
          "price": 100
        },
        {
          "sku": "Test Product 2",
          "name": "Test Product 2",
          "price": 200
        }
      ]
    }
  }
}

Leave a Reply