Back to Top

How to use GraphQL API in Opencart?

Updated 6 June 2023


OpenCart is an open-source eCommerce platform, based on PHP and MVC architecture for online merchants. Opencart provides a great number of features that are responsible to control your store.

It allows a professional and reliable foundation from which to build a successful online store.

This article describes how a developer can use GraphQL API in Opencart.

An Overview of GraphQL

GraphQl is an alternative to REST and SOAP API. It allows you to fetch the data easily using query language. It is a modern way to fetch data from API calls and makes API responses more efficient and reduces network overhead.

GraphQL provides a complete and understandable description of the data in your API. The query returns data in a specified format usually in the form of a JSON string as fetched from the server end.

Searching for an experienced
Opencart Company ?
Find out More

In Short, the operations of GraphQL:

  1. queries – for reading and receiving information.
  2. mutations – needed for taking actions, creating data, and modifying information.
  3. subscriptions – it provides the opportunity to get data from the server in real-time automatically after a while, for instance, for notifications.

Use of GraphQL for Developers?

  • Developers can request the exact data they need, which results in smaller and more efficient data transfers.
  • It provides a flexible data model, which allows developers to query data more naturally and intuitively. This makes it easier to build complex data-driven applications.
  • Developers can also create custom GraphQL queries, mutations, and types, allowing them to extend the platform’s default schema and can create custom functionality that meets their specific requirements.
  • GraphQL solves this with a single endpoint and a strictly-typed schema. By design, the schema defines the resources available for retrieval in addition to the accepted parameters when fetching that data.

Comparison between graphQL API and REST API

QueryingWith GraphQL, you can retrieve all the needed data in a single request and specify which fields and data you want.With REST APIs, you typically make separate requests for each resource or the endpoint you want to access.
CachingGraphQL API caching can be more challenging because each request is unique and may require a different data set.REST APIs are often easier to cache than GraphQL because the URLs are used as the cache keys.
Learning CurveGraphQL has a steeper learning curve, and it may take longer to become proficient with the technology.REST APIs are simpler to understand and use, and a wealth of documentation and tooling is available.
PerformanceGraphQL can be more efficient than REST APIs for some use cases because it reduces over-fetching and under-fetching of data. REST APIs can be faster when only a small amount of data is required.

Although choosing GraphQl API is the best way instead of using REST API.

How to Implement?

Step 1: GraphQL PHP Library – Just install the library webonyx/graphql-php in opencart instance using code.

$ composer require webonyx/graphql-php

Step 2: Create a Controller file within the opencart root catalog directory like “catalog/controller/api/graphql/usage.php”.

Step 3: After installing the GraphQL Package, include the following Classes in your controller file.

  * Webkul Software.
  * @category Webkul
  * @package Opencart Module Tutorial
  * @author Webkul
  * @license

use GraphQL\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;

Step 4: Create an Index method inside the controller class and define the schema for your QueryType.

class ControllerApiGraphqlUsage extends Controller {
 public static $ProductType;
 public static $ReviewInput;
    public function index () {	
        $schema = new Schema ([
          'query' => $RootQueryType,
          'mutation' => $MutationType

Note – Here we have added the query type and mutation type, similarly we can define the subscription type schema.

Step 5: Now we have to define the Query Type Object.

$RootQueryType = new ObjectType ([

  'name' => 'RootQuery',
  'fields' => function () { return [
  'products' => [
    'type' => Type::listOf (self::$ProductType),
    'args' => [
       'filter_category_id' => Type::int (),
       'filter_sub_category' => Type::int (),
       'filter_filter' => Type::string (),
       'filter_name' => Type::string (),
       'filter_tag' => Type::string (),
       'filter_description' => Type::string (),
       'filter_model' => Type::string (),
       'filter_price' => Type::string (),
       'filter_quantity' => Type::string (),
       'filter_status' => Type::string (),
       'filter_image' => Type::string (),
       'filter_manufacturer_id' => Type::int (),
       'sort' => Type::string (),
       'order' => Type::string (),
       'start' => Type::int (),
       'limit' => Type::int ()
    'resolve' => function ($root, $args) {
        $key_mapper = [
               'name' => '',
               'price' => 'p.price',
               'rating' => 'rating',
               'quantity' => 'p.model',
               'date_added' => 'p.date_added',
                'sort_order' => 'p.sort_order'

        $args['sort'] = isset($args['sort'])? in_array($key_mapper[$args['sort']], array_keys($key_mapper)) ? $key_mapper[$args['sort']] : '': '';

        $products = $this->model_catalog_product->getProducts($args);

        return $products;


Object Type has a Field named “products” with a backed resolver function that returns the data using the “getProducts function ” that has parameter $args which is used when we can specific product data via filter_price or other arguments.

Step 6: RootQueryType object has a link with the ProductType list, include the ProductType object in the file.

 self::$ProductType = new ObjectType ([
            'name' => 'Product',
            'fields'  => function () { return [
                'product_id' => [
                    'type' => Type::id ()
                'name' => [
                    'type' => Type::string ()
                'description' => [
                    'type' => Type::string (),
                    'resolve' => function ($root, $args) {
                        return strip_tags(html_entity_decode($root['description']));
                'meta_title' => [
                    'type' => Type::string ()
                'meta_description' => [
                    'type' => Type::string ()
                'model' => [
                    'type' => Type::string ()
                'quantity' => [
                    'type' => Type::string ()
                'price' => [
                    'type' => Type::string ()
                'special' => [
                    'type' => Type::string ()
            ]; }

Step 7: Define the Mutation Object Type in the controller file.

  $MutationType = new ObjectType ([
            'name' => 'MutationType',
            'fields'  => function () { return [
                'addReview' => [
                    'type' => Type::id (),
                    'args' => [
                        'product_id' => Type::nonNull (Type::id ()),
                        'input' => Type::nonNull (self::$ReviewInput)
                    'resolve' => function ($root, $args) {
                        $this->load->model ('catalog/review');
                        return $this->model_catalog_review->addReview($args['product_id'], $args['input']);

Mutation Object Type has a Field named “addReview” with a backed resolver function that returns the last added review id on the specific arguments via product_id, input using the “addReview”.

Step 8: Mutation Object type is having two arguments one is ‘product_id’ and the second one is ‘input’. Here Input argument will contain the required input parameters to add the review on the specific product.

      static::$ReviewInput = new InputObjectType ([
            'name' => 'ReviewInput',
            'fields'  => function () { return [
                'name' => [
                    'type' => Type::nonNull (Type::string ())
                'rating' => [
                    'type' => Type::nonNull (Type::int ())
                'text' => [
                    'type' => Type::nonNull (Type::string ())
            ]; }

Step 9: At last, include the code for query execution.

 try {
    $rawBody = file_get_contents('php://input');
    $data = json_decode($rawBody ?: '', true);
      $requestString = $data['query'] ?? null;
      $operationName = $data['operation'] ?? null;
      $variableValues = $data['variables'] ?? null;
    if (!(is_object ($variableValues) || is_array($variableValues)))
        $variableValues = json_decode($variableValues, True);
        $rootValue = ['prefix' => 'You said: '];
        $result = GraphQL::executeQuery($schema, $requestString, null,              $this, $variableValues);

     } catch (\Exception $e) {
            $result = [
                'error' => [
                    'message' => $e
		header('Content-Type: application/json; charset=UTF-8');
		echo json_encode($result);


GraphQL class has an executeQuery function that is used to process the Requested Query. The ExecuteQuery function works along with root Value and return the Data as per defined type, field, and resolver functions.

Execution of Graphql API

The GraphQL endpoint in Opencart is api/graphql/usage. To access the GraphQL URL, set the GraphQL endpoint by entering HTTP or https://<opencart base-url>index.php?route=api/graphql/usage .

we used the postman for the execution of the query, you can also use another IDE.

1. Query Type

The query type is used for retrieving the data.


2. Mutation Type –

Mutation type query is used to modify the data or make some operation with the data.


Result – Navigate to the catalog->reviews tab at admin end, new review has been added to the product.


Thank You!

If you need custom Opencart Development services then feel free to reach us and also explore our exclusive range of Opencart Extensions.

!! Have a Great Day Ahead !!

. . .

Leave a Comment

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

Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home