How to create a graphql schema for magento 2 custom module with custom table?

We have many articles to get the list of Orders, Cms Page, Customers, Customer’s Orders using graphql in magento 2. But Today i am going to write an article to get the list of data from Magento 2 Custom module. With the custom table using Graphql.

To achieve this we want to create a simple module.Here we are going to create a custom module with the custom database table. Please refer How to create a custom module with custom table in Magento 2 article to get an understand about creating a custom module.

I will consider the custom module FAQ ( Consider the Package name as Ayakil, Module name as Faq)for a website. Which have question, answer and image columns in the database table to cover this article.Apart from creating the custom module I will explain the essential steps to achieve the goal.

Step 1 – Create module.xml.
Step 2 – Create schema.graphqls.
Step 3 – Create Resolver file.
Step 4 – Create Data Provider file

Magento 2 Module structure
Custom Module Structure

I am not worrying about the lengthy page. Because i want to explain as much as what i tried to achieve and what are the mistakes i did.So this may help some one.

Step 1 – creating module.xml under directory etc.I am not going to mention about registration.php. As every one aware about that. I want to mention some thing here about module.xml. Since our module is depends on Graphql, we want to give dependency in module.xml.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Ayakil_Faq" setup_version="2.0.0">
        <sequence>
            <module name="Magento_GraphQl"/>
            <module name="Magento_Backend"/>
        </sequence>
	</module>
</config>

Step 2 – GraphQl module must include the schema.graphqls under etc directory, which is handling the query the main part of GraphQl. This file should go under app/etc/schema.graphqls

type Query {
    faqs : [Faqs] @resolver( class: "Ayakil\\Faq\\Model\\Resolver\\Faq") @doc(description: "Get list of active answered FAQS")
}

type Faqs {
    question : String  @doc(description: "Question")
    answer : String  @doc(description: "Answer")
    faq_image : String  @doc(description: "Image if available")
}

In the schema.grapqls file naming convention doesn’t have any restriction. But better to restrict with the module scope to simply identify the code.Here i am using faqs. Because our module is going to retrieve the question and answer for our website’s FAQ page. Another important thing here want to consider is the resolver file path [ class: “Ayakil\Faq\Model\Resolver\Faq”]. we want to give in the main query.

Step 3 – Creating resolver file under Model directory. File path should be app/code/Ayakil/Faq/Model/Resolver/Faq.php as mentioned in the schema.grapqls file.

<?php
namespace Ayakil\Faq\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;

class Faq implements ResolverInterface
{
    private $faqDataProvider;
    /**
     * @param DataProvider\Faq $faqRepository
     */
    public function __construct(
        \Ayakil\Faq\Model\Resolver\DataProvider\Faq $faqDataProvider
    ) {
        $this->faqDataProvider = $faqDataProvider;
    }

    /**
     * @inheritdoc
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        $faqData = $this->faqDataProvider->getFaq();
        return $faqData;
    }
}

Step 4 – Creating Data provider file.File path should be app/code/Ayakil/Faq/Model/Resolver/DataProvider/Faq.php

<?php
namespace Ayakil\Faq\Model\Resolver\DataProvider;

class Faq
{
    protected $_faqFactory;

    public function __construct(
        \Ayakil\Faq\Model\FaqFactory $faqFactory
        )
    {
        $this->_faqFactory  = $faqFactory;
    }
    /**
     * @params int $id
     * this function return all the word of the day by id
     **/
    public function getFaq( )
    {
        try {
            $collection = $this->_faqFactory->create()->getCollection();
            $collection->addFieldToFilter('faq_active',1);
            $collection->setOrder('short_order', 'ASC');
            $faqData = $collection->getData();

        } catch (NoSuchEntityException $e) {
            throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
        }
        return $faqData;
    }
}

This data provider file simply return the data collection. All logic set in the collection and the function getFaq() return all the active question and answer details.After run upgrade command to install the module we can check the graphQl query response.To check the response you can use some extensions like ChromeiQL or Altair GraphQL addon. To get clear understand about GraphQl and how to access it follow What is GraphQl and how to access it?. I am using Altair GraphQL Addon.

To check our query we want to set up the endpoint.It is usually coming like <magento_root_url>/graphql. Ex :- http://ayakil.local/graphql.

sample GraphQl query & answer
sample GraphQl Request Payload and Result

That’s it. Have a nice day.Enjoy coding , Learn , Experience , Teach and Help.

Leave a Reply

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