How to Create Custom GraphQL in Magento 2?

GraphQL is a data query language developed for internal use by Facebook in 2012 before being publicly released in 2015. Magento implements GraphQL to provide an alternative to REST and SOAP web APIs for front-end development.

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API.

If you are looking for a way to create custom GraphQL or how to retrieve custom table data using GraphQL, you have come to the right place. 

In this article, We will explain how to create custom GraphQL or get custom table data using GraphQL. 

To implement GraphQL in magento2 you have to create the following files:-

Steps To Create Custom GraphQL in Magento 2

STEP 1:  Create this file to register your module: registration.php

Path: app/code/DCKAP/CustomCollection/registration.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'DCKAP_CustomCollection',
    __DIR__
);

STEP 2: To define your module name you have to create: module.xml

Path: app/code/DCKAP/CustomCollection/etc/module.xml

<?xml version="1.0"?>
<!--
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="DCKAP_CustomCollection" setup_version="1.0.0">
        <sequence>
            <module name="Magento_GraphQl"/>
        </sequence>
    </module>
</config>

STEP 3: Let’s create a custom table using db schema: db_schema.xml

Path: app/code/DCKAP/CustomCollection/etc/db_schema.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!--
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
*/
--> 
<schema xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="dckap_products" resource="default" engine="innodb" comment="DCKAP Products Entity">
        <column xsi:type="int" name="entity_id" unsigned="true" nullable="false" identity="true" comment="Entity ID" />
        <column xsi:type="varchar" name="title" nullable="false" comment="Title" length="255" />
        <column xsi:type="text" name="description" nullable="true" comment="Description" />
        <constraint xsi:type="primary" referenceId="PRIMARY">
            <column name="entity_id" />
        </constraint>
    </table>
</schema>

Run setup upgrade command to install the module.

php bin/magento setup:upgrade

Now Insert some dummy data in dckap_products table.

INSERT INTO `dckap_products` (`entity_id`, `title`, `description`) VALUES

(1, ‘DCKAP Integrator’, ‘Streamline your Integration. Maximize efficiency & profitability by delivering a consistent customer experience across sales channels. DCKAP Integrator is the No. 1 ERP integration platform for distributors.’),

(2, ‘DCKAP PIM’, ‘Automate Your Product Data. DCKAP PIM simplifies product data management for distributors. Get your customers the details they need – faster – no matter where they shop.’),

(3, ‘DCKAP Headless’, ‘Embrace Flexibility with Headless Commerce. The future of eCommerce is Headless. DCKAP Headless makes it easy for distributors to cater to B2B customers’ every need online – now and into the future.’),

(4, ‘Zircly’, ‘ Everything Starts With Employee Experience. Start building an engaged, transparent, and efficient workplace today. Zircly is an Employee Experience Platform from DCKAP to help you keep up with the times.’);

STEP 4: Create DCKAP_Products model : Products.php

Path: app/code/DCKAP/CustomCollection/Model/Products.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

namespace DCKAP\CustomCollection\Model;
 
use Magento\Framework\Model\AbstractModel;
 
class Products extends AbstractModel
{
    public function _construct()
    {
        $this->_init(\DCKAP\CustomCollection\Model\ResourceModel\Products::class);
    }
}

STEP 5: Next create a DCKAP_Products Resource model : Products.php

Path: app/code/DCKAP/CustomCollection/Model/ResourceModel/Products.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

namespace DCKAP\CustomCollection\Model\ResourceModel;
 
class Products extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    protected function _construct()
    {
        $this->_init("dckap_products", "entity_id");
    }
}

STEP 6: Now create a Collection model: Collection.php

Path: app/code/DCKAP/CustomCollection/Model/ResourceModel/Products/Collection.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

namespace DCKAP\CustomCollection\Model\ResourceModel\Products;
 
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    public function _construct()
    {
        $this->_init(
            \DCKAP\CustomCollection\Model\Products::class,
            \DCKAP\CustomCollection\Model\ResourceModel\Products::class
        );
    }
}

STEP 7:  Now create schema.graphqls to define the structure of queries and mutations: schema.graphqls.

Path: app/code/DCKAP/etc/schema.graphqls

type Query
{
    getDCKAPProductsById(id: Int @doc(description: "DCKAP Products ID. Must be an integer")): DCKAPProductsById
        @resolver(class: "DCKAP\\CustomCollection\\Model\\Resolver\\ProductsById")
        @doc(description: "Retrieve a DCKAP Products by id.")

    getDCKAPProductsByTitle (title: String @doc(description: "DCKAP Products Title. Must be string")): DCKAPProductsByTitle
        @resolver(class: "DCKAP\\CustomCollection\\Model\\Resolver\\ProductsByTitle")
        @doc(description: "Retrieve a DCKAP Products by Title.")   

    getAllProductsCollection: DCKAPProductsCollection
        @resolver(class: "DCKAP\\CustomCollection\\Model\\Resolver\\GetAllProducts")
        @doc(description: "Retrieve All Products Collection")             
}
type DCKAPProductsById
{
    id: Int
    title: String
    description: String
}

type DCKAPProductsByTitle
{
    id: Int
    title: String
    description: String
}

type DCKAPProductsCollection @doc(description: "Get All DCKAP Products Details") {
    allProducts: [AllDCKAPProductsRecords] @doc(description: "An array containing the all the DCKAP Products Collection")
}

type AllDCKAPProductsRecords {
    entity_id: Int @doc(description: "Product Id")
    title: String @doc(description: "Product Name")
    description: String @doc(description: "Product Description")
}

STEP 8:  Finally Create DCKAP_Products Resolver Model : ProductsById.php

Path: app/code/DCKAP/CustomCollection/Model/Resolver/ProductsById.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

namespace DCKAP\CustomCollection\Model\Resolver;
 
use DCKAP\CustomCollection\Model\ResourceModel\Products\Collection;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
 
class ProductsById implements \Magento\Framework\GraphQl\Query\ResolverInterface
{
    /**
     * @var Collection
     */
    private Collection $collection;
 
    /**
     * @param Collection $collection
     */
    public function __construct(Collection $collection)
    {
        $this->collection = $collection;
    }
 
    /**
     * @inheritDoc
     */
    public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
    {
        if (!isset($args['id'])) {
            throw new GraphQlInputException(__("Id is required field."));
        }
 
        $id = $args['id'];
        $collection = $this->collection->addFieldToFilter("entity_id", $id);
        if (!$collection->count()) {
            return [];
        }
 
        $productData = [];
 
        foreach ($collection->getData() as $item) {
            $productData = [
                "id"    => $item["entity_id"],
                "title"    => $item["title"],
                "description"    => $item["description"]
            ];
        }
 
        return $productData;
    }
}

STEP 9: If you want to get the data by title then create another DCKAP_Products Resolver Model : ProductsByTitle.php

Path: app/code/DCKAP/CustomCollection/Model/Resolver/ProductsByTitle.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

namespace DCKAP\CustomCollection\Model\Resolver;
 
use DCKAP\CustomCollection\Model\ResourceModel\Products\Collection;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
 
class ProductsByTitle implements \Magento\Framework\GraphQl\Query\ResolverInterface
{
    /**
     * @var Collection
     */
    private Collection $collection;
 
    /**
     * @param Collection $collection
     */
    public function __construct(Collection $collection)
    {
        $this->collection = $collection;
    }
 
    /**
     * @inheritDoc
     */
    public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
    {
        if (!isset($args['title'])) {
            throw new GraphQlInputException(__("Title is required field."));
        }
 
        $title = $args['title'];
        $collection = $this->collection->addFieldToFilter("title", $title);
        if (!$collection->count()) {
            return [];
        }
 
        $productData = [];
 
        foreach ($collection->getData() as $item) {
            $productData = [
                "id"    => $item["entity_id"],
                "title"    => $item["title"],
                "description"    => $item["description"]
            ];
        }
 
        return $productData;
    }
}

STEP 10: Now lastly If you want to get all the data from Custom Table DCKAP_Products then create another DCKAP_Products Resolver Model : GetAllProducts.php

Path: app/code/DCKAP/CustomCollection/Model/Resolver/GetAllProducts.php

<?php
/**
 * DCKAP_CustomCollection Extension
 *
 * @category  DCKAP
 * @package   DCKAP_CustomCollection
 * @author    DCKAP
 */

namespace DCKAP\CustomCollection\Model\Resolver;
 
use DCKAP\CustomCollection\Model\ResourceModel\Products\Collection;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
 
class GetAllProducts implements \Magento\Framework\GraphQl\Query\ResolverInterface
{
    /**
     * @var Collection
     */
    private Collection $collection;
 
    /**
     * @param Collection $collection
     */
    public function __construct(
        Collection $collection
    )
    {
        $this->collection = $collection;
    }
 
    /**
     * @inheritDoc
     */
    public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
    {

        try {

            $collection = $this->collection;
            if (!$collection->count()) {
                return [];
            }

            $dckapProductsCollection['allProducts'] = [];
                foreach ($collection->getData() as $item) {
                    $dckapProductsCollection['allProducts'][$item["entity_id"]]['entity_id'] = $item["entity_id"];
                    $dckapProductsCollection['allProducts'][$item["entity_id"]]['title'] = $item["title"];
                    $dckapProductsCollection['allProducts'][$item["entity_id"]]['description'] = $item["description"];
                }
                
                } catch (NoSuchEntityException $e) {
                    throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
            }

        return $dckapProductsCollection;
    }
}
  • Products By Id: Request (Query Get DCKAP Product By Id : Where 1 is DCKAP Product Id)
query {
  getDCKAPProductsById(
    id: 1
  ) {
    id
    title
    description
  }
}
  • Products By Id: Response 
{
  "data": {
    "getDCKAPProductsById": {
      "id": 1,
      "title": "DCKAP Integrator",
      "description": "Streamline your Integration. Maximize efficiency & profitability by delivering a consistent customer experience across sales channels. DCKAP Integrator is the No. 1 ERP integration platform for distributors."
    }
  }
}
  • Products By Title: Request  Query Get DCKAP Product By Title: Where DCKAP PIM is DCKAP Product Title)
query {
  getDCKAPProductsByTitle(
    title: "DCKAP PIM"
  ) {
    id
    title
    description
  }
}
  • Products By Title: Response 
{
  "data": {
    "getDCKAPProductsById": {
      "id": 1,
      "title": "DCKAP Integrator",
      "description": "Streamline your Integration. Maximize efficiency & profitability by delivering a consistent customer experience across sales channels. DCKAP Integrator is the No. 1 ERP integration platform for distributors."
    }
  }
}
  • Get All Product Collection: Request (Query Get All DCKAP Product Collection)
{
  getAllProductsCollection {
    allProducts {
    entity_id
    title
    description
    }
  }
}
  • Get All Product Collection: Response
{
  "data": {
    "getAllProductsCollection": {
      "allProducts": [
        {
          "entity_id": 1,
          "title": "DCKAP Integrator",
          "description": "Streamline your Integration. Maximize efficiency & profitability by delivering a consistent customer experience across sales channels. DCKAP Integrator is the No. 1 ERP integration platform for distributors."
        },
        {
          "entity_id": 2,
          "title": "DCKAP PIM",
          "description": "Automate Your Product Data. DCKAP PIM simplifies product data management for distributors. Get your customers the details they need – faster – no matter where they shop."
        },
        {
          "entity_id": 3,
          "title": "DCKAP Headless",
          "description": "Embrace Flexibility with Headless Commerce. The future of eCommerce is Headless. DCKAP Headless makes it easy for distributors to cater to B2B customers’ every need online – now and into the future."
        },
        {
          "entity_id": 4,
          "title": "Zircly",
          "description": "Everything Starts With Employee Experience.Start building an engaged, transparent and efficient workplace today. Zircly is an Employee Experience Platform from DCKAP to help you keep up with the times."
        }
      ]
    }
  }
}

GraphQL in Magento 2 for Enhanced Efficiency and Flexibility

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. The above data you can use to create a custom table collection GraphQL API in (Adobe Commerce) magento 2 that is more efficient and flexible than traditional REST APIs. 

As an alternative to the REST, GraphQL lets developers construct requests that pull data from multiple data sources in a single API call. 

About The Author

We take the guesswork out of ecommerce.
Schedule a consultation call today