Creating a Custom GraphQL for Magento 2 Products

Creating a Custom GraphQL for Products in Magento2

Magento 2’s native GraphQL API is powerful, but sometimes you need more control or custom functionality that the default product queries can’t provide. That’s why creating a custom GraphQL for Magento 2 products is a great solution when you want more tailored data, lightweight responses, or to expose additional product attributes to your frontend or mobile apps.

In this blog post, we’ll show you how to create a custom GraphQL endpoint for Magento 2 products — fully optimized for performance, extensibility, and SEO-friendliness.

Let’s get started! 🚀

🔍 Why Create a Custom GraphQL for Products?

Magento’s default GraphQL covers a lot, but what if you want to:

  • Get custom product attributes not available in the default query?
  • Filter products based on business-specific logic?
  • Return lightweight product data for a custom frontend?

That’s where a custom GraphQL comes in.

🧱 Step-by-Step: Build Custom Product GraphQL in Magento 2

Let’s walk through how to set this up.

🧩 1. Module Structure

Create your module: SbDevBlog_CustomProductGraphQL

Folder structure:

app/code/SbDevBlog/CustomProductGraphQL
├── etc
│ └── module.xml
├── registration.php
├── etc/graphql
│ └── schema.graphqls
├── Model
│ └── Resolver
│ └── CustomProduct.php
├── composer.json

📜 2. schema.graphqls – Define Your GraphQL Schema

type Query {
  customProducts(sku: String): [CustomProductOutput] @resolver(class: "SbDevBlog\\CustomProductGraphQL\\Model\\Resolver\\CustomProduct")
}

type CustomProductOutput {
  id: Int
  name: String
  sku: String
  price: Float
  status: Int
}

🧠 3. Resolver Logic – Pull Product Data

In Model/Resolver/CustomProduct.php:

namespace SbDevBlog\CustomProductGraphQL\Model\Resolver;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Exception\NoSuchEntityException;

class CustomProduct implements ResolverInterface
{
    protected $productRepository;

    public function __construct(ProductRepositoryInterface $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    public function resolve($field, $context, ResolveInfo $info, array $value = null, array $args = null)
    {
        $sku = $args['sku'] ?? null;

        if (!$sku) {
            return [];
        }

        try {
            $product = $this->productRepository->get($sku);

            return [[
                'id'     => (int)$product->getId(),
                'name'   => $product->getName(),
                'sku'    => $product->getSku(),
                'price'  => (float)$product->getPrice(),
                'status' => (int)$product->getStatus()
            ]];
        } catch (NoSuchEntityException $e) {
            return [];
        }
    }
}

🧪 4. Test in Postman or Altair

Use this GraphQL query.

query {
  customProducts(sku: "24-MB01") {
    id
    name
    sku
    price
    status
  }
}

Expected Output:

{
  "data": {
    "customProducts": [
      {
        "id": 123,
        "name": "Push It Messenger Bag",
        "sku": "24-MB01",
        "price": 45,
        "status": 1
      }
    ]
  }
}

🔧 Bonus Tips

  • 🔄 Add filtering or pagination to make it more dynamic.
  • 🎯 Use Input Types if you’re passing complex parameters.
  • 📦 Cache results using Magento’s GraphQL cache layer for better performance.

🧘 Final Thoughts: Creating a Custom GraphQL for Magento 2 Products

Creating a custom GraphQL for Magento 2 products opens the door to better flexibility, performance, and API design tailored to your business needs.

Whether you’re integrating with a headless frontend or syncing product data with third-party platforms — building your own query gives you the freedom Magento’s core API may not offer out of the box.

Stay tuned and follow SB Dev Blog for more Magento 2 development tutorials, tips, and tricks!

Leave a Reply

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