How to create a Graphql schema by passing argument for custom magento 2.3 module with custom table?

Good Day for every one.Today’s article is going to cover the GraphQl schema for custom table and retrieve the data by passing an argument.
For this i am going to use a custom magento 2 module.This module help the admin to add the Word of the Day to show in the home page.Here we are going to pass the Current day as argument. And retrieve the Word of the day collection to the home page.

The word of the day module contain 5 columns in its database table. Word, Word Class, Meaning, Example Sentence and the Date. As our previous article we have few steps to achieve this task.Following are the main steps to consider apart from creating the custom module.All other stuffs related to custom module i am not going to explain here.

Step 1 – How to write schema.graphqls.
Step 2 – Writing Resolver file.
Step 3 – Create Data Provider file.

Step 1 is one of the main part where we want to pass our argument to GraphQl query. schema.graphqls file should go under app/etc/schema.graphqls

type Query {
wordOfTheDayByDate (
        date_to_show: String @doc(description: "Date of current day")
    ): [WodCollection] @resolver(class: "Ayakil\\Wordoftheday\\Model\\Resolver\\Wordoftheday") @doc(description: "The wordOfTheDayByDate query returns wod contents according to provided date")
}
type WodCollection @doc(description: "WodCollection defines all wod information") {
    word : String  @doc(description: "Word of the day")
    verb : String  @doc(description: "verb of the word")
    meaning : String  @doc(description: "meaning of the word")
    details : String  @doc(description: "details of the word")
}

In schema.graphqls we are passing date_to_show as our argument.We want to pass the argument to our resolver and get the data accordingly.Here i am using wordOfTheDayByDate.when we going to get the data we want to use this wordOfTheDayByDate in the query.Another main stuff we want to consider is the resolver file path.Path is [ class: “Ayakil\Wordoftheday\Model\Resolver\Wordoftheday”].
type WodCollection{} is our return data array. We want to pass the word, verb,meaning,details in wordOfTheDayByDate query along with date_to_show as argument.

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

<?php
namespace Ayakil\Wordoftheday\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 Wordoftheday implements ResolverInterface
{
    private $wordofthedayDataProvider;
    /**
     * @param DataProvider\Wordoftheday $wordofthedayRepository
     */
    public function __construct(
        \Ayakil\Wordoftheday\Model\Resolver\DataProvider\Wordoftheday $wordofthedayDataProvider
    ) {
        $this->wordofthedayDataProvider = $wordofthedayDataProvider;
    }

    /**
     * @inheritdoc
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        //by Date
        $date_to_show = $this->getDates( $args);
        $wordofthedayData = $this->wordofthedayDataProvider->getWordofthedayByDate( $date_to_show );
        return $wordofthedayData;
    }

    private function getDates(array $args)
    {
        if (!isset($args['date_to_show'])) {
            throw new GraphQlInputException(__('"date should be specified'));
        }
        return $args['date_to_show'];
    }
}

Important things to capture here in this resolver file is function getDates(), In this function we are passing our arguments and return the argument.To capture the exact argument we want to pass the exact argument name which we given in the schema.graphqls Query. Here we passed date_to_show, so we want to get it as $args[‘date_to_show’]. Why i am mentioning this here was i had to spend more time to realize this as i did this very first time.

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

<?php

namespace Ayakil\Wordoftheday\Model\Resolver\DataProvider;

class Wordoftheday
{
    protected $_wordofthedayFactory;

    public function __construct(
        \Ayakil\Wordoftheday\Model\WordofthedayFactory $wordofthedayFactory
        )
    {
        $this->_wordofthedayFactory  = $wordofthedayFactory;
    }
    
    /**
     * @params string $date_to_show
     * this function return all the word of the day by a date
     **/
    public function getWordofthedayByDate( string $date_to_show): array
    {
        try {
            $wordofthedayData = [];
            $collection = $this->_wordofthedayFactory->create()->getCollection();
            $collection->addFieldToFilter('date_to_show',$date_to_show);
            $collection->getData();

            foreach($collection as $wod){
                $wod_id = $wod->getId();
                $wordofthedayData[$wod_id]['word'] = $wod->getWord();
                $wordofthedayData[$wod_id]['verb'] = $wod->getVerb();
                $wordofthedayData[$wod_id]['meaning'] = $wod->getMeaning();
                $wordofthedayData[$wod_id]['details'] = $wod->getDetails();
            }

        } catch (NoSuchEntityException $e) {
            throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
        }
        return $wordofthedayData;
        //return $wordofthedayData;
    }//End of function getWordofthedayByDate
}

This data provider file simply return the data collection. All logic set in the collection and the function getWordofthedayByDate() return all the word of the day data to relevant day.While we setup the data array ( $wordofthedayData = [];) pass the id to the array as mention in the code to avoid null value return.
Ex: $wod_id$wordofthedayData[$wod_id][‘word’] = $wod->getWord();
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.
Here is the query and result.

word of the day sample query and result

Sample GraphQl Query

query wordOfTheDayByDate {
  wordOfTheDayByDate( date_to_show : "2019-08-16"){
    word
    verb
    meaning
    details
  }
}

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 *