Fetching CMS Pages

Fetching CMS Pages Using GraphQL in Magento 2

GraphQL has revolutionized how modern web applications interact with data. Its ability to fetch precisely the data you need in a single request makes it a powerful tool for developers. Magento 2 fully embraces GraphQL, enabling efficient retrieval and management of CMS pages with minimal overhead.

This guide provides a step-by-step walkthrough for creating a custom Magento 2 module to fetch all CMS pages using GraphQL. From setting up module essentials to crafting and testing your GraphQL query, this comprehensive tutorial has you covered.

Why Use GraphQL for CMS Pages in Magento 2?

GraphQL is a modern query language that enables efficient, precise, and flexible data retrieval. For managing CMS pages in Magento 2, GraphQL offers significant advantages over traditional REST and SOAP APIs. By leveraging GraphQL, developers can streamline data access, minimize payloads, and enhance the overall performance of their applications.

Key Benefits of GraphQL for CMS Pages

Benefit Description
Precise Data Retrieval Fetch only the specific data you need, avoiding unnecessary overhead.
Single Request for Multiple Data Combine data from various sources into a single, efficient request.
Simplified Queries Replace complex API interactions with intuitive, human-readable GraphQL queries.

Why Choose GraphQL?

  • Reduced Payload Size: Requesting only necessary fields minimizes data transfer, improving performance.
  • Enhanced Flexibility: Developers can request custom data structures without needing new endpoints.
  • Streamlined Development: Intuitive syntax reduces the learning curve and speeds up integration.

Prerequisites

Before diving into GraphQL for CMS pages, ensure you meet the following requirements:

Requirement Details
Magento 2 Installation A fully functional Magento 2 instance installed and running.
Module Development Basics Familiarity with creating and managing custom Magento 2 modules.
GraphQL Understanding A basic grasp of GraphQL concepts and how it interacts with APIs.

GraphQL provides a dynamic, efficient way to manage CMS pages in Magento 2. Its precise querying capabilities reduce payload sizes, simplify development workflows, and enhance performance. By adopting GraphQL, developers can improve data management and create more responsive, scalable Magento 2 applications.

Embrace GraphQL for its flexibility, intuitive syntax, and ability to revolutionize your CMS page management in Magento 2.

Fetching CMS Pages with GraphQL

Creating a Magento 2 module to fetch CMS pages via GraphQL is a powerful way to optimize data retrieval for your storefront. This guide outlines the step-by-step process to achieve this.

Step Details
Step 1: Module Initialization Set up core files like registration.php and module.xml to initialize your custom module.
Step 2: Define GraphQL Schema Create a GraphQL schema file to outline the query structure for retrieving CMS pages data.
Step 3: Implement the Resolver Develop the resolver logic to handle CMS page data fetching from the database effectively.
Step 4: Validate the Query Use GraphQL clients like Altair or Postman to test and validate your custom query functionality.

Step 1: Set Up the Basic Structure of Your Custom Module

Creating a custom module in Magento 2 requires setting up the foundational files and configurations. Below, we outline the necessary steps to define your module structure.

Files to Create for Module Definition:

  • registration.php
    This file registers your module within Magento’s system and should be placed in the root of your module directory.

    Path: app/code/Emmo/CmsPagesGraphQl/registration.php

    PHP Code for Module Registration

    <?php

    \Magento\Framework\Component\ComponentRegistrar::register(

    \Magento\Framework\Component\ComponentRegistrar::MODULE,

    'Emmo_CmsPagesGraphQl',

    __DIR__

    );

  • module.xml
    This configuration file is required for Magento to recognize the module. It should be placed inside the etc directory of your module. The file also defines module dependencies.

    Path:app/code/Emmo/CmsPagesGraphQl/etc/module.xml

    XML Configuration for Module

    <?xml version="1.0"?>

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">

    <module name="Emmo_CmsPagesGraphQl">

    <sequence>

    <module name="Magento_Cms"/>

    <module name="Magento_GraphQl"/>

    </sequence>

    </module>

    </config>

  • Explanation
    • Magento_Cms: Ensures your module can interact with the cms data.
    • Magento_GraphQl: Integrates GraphQL functionality for the custom module.

Directory Structure

Here’s how your module directory should be structured at this point:

Module Directory Structure

app/code/Emmo/CmsPagesGraphQl

├── registration.php

└── etc

└── module.xml


By defining these files, you’ve completed the first step of module creation. In the next steps, you will add more functionality, such as custom GraphQL queries, models, and other logic to extend your Magento store.

Step 2: Defining the GraphQL Schema

A critical component of every GraphQL module is the schema.graphqls file. This file defines the structure of queries and the data they return. In this step, you will create a schema that enables fetching CMS pages efficiently.

Purpose of the Schema

The schema.graphqls file:

  • Describes the queries available in the GraphQL API.
  • Defines the data types and their relationships.
  • Maps queries to resolvers, which fetch the requested data.

File Location

Path: app/code/Emmo/CmsPagesGraphQl/etc/schema.graphqls

Sample Schema

Below is a detailed schema for retrieving all CMS pages:

GraphQL Schema Definition

schema.graphqls

type Query {

cmsPages: CmsPages @resolver(class: "Emmo\\CmsPagesGraphQl\\Model\\Resolver\\CmsPages") @doc(description: "Retrieve all CMS static pages.")

cmsPage(identifier: String): PagesRecord @resolver(class: "Emmo\\CmsPagesGraphQl\\Model\\Resolver\\SinglePage") @doc(description: "Retrieve a single CMS page by its identifier.")

}

type CmsPages @doc(description: "Represents CMS Pages data.") {

allPages: [PagesRecord] @doc(description: "Array of all CMS pages.")

totalPages: Int @doc(description: "Total number of CMS pages available.")

}

type PagesRecord {

identifier: String @doc(description: "Unique identifier for the CMS page.")

name: String @doc(description: "Title of the CMS page.")

page_layout: String @doc(description: "Layout assigned to the CMS page.")

content: String @doc(description: "Main content of the CMS page.")

creation_time: String @doc(description: "Date and time the page was created.")

update_time: String @doc(description: "Date and time of the last update.")

}

Key Components Explained

Query Type:

  • Defines the root queries available to clients.
  • Includes cmsPages for fetching all CMS pages and cmsPage for retrieving specific pages using an identifier.

CmsPages Type:

  • Represents the overall structure of CMS data.
  • Includes allPages for an array of page records and totalPages for the count of available pages.

PagesRecord Type:

  • Represents individual CMS page details.
  • Attributes include:
    • identifier: Unique key for the page.
    • name: Title or name of the page.
    • page_layout: Assigned layout for the page.
    • content: HTML content or body of the page.
    • creation_time: When the page was created.
    • update_time: Last modification date.

Enhancements for Better Usability

  • Custom Filters: Add arguments like titleContains or updatedAfter to the cmsPages query for more flexible searches.
  • Error Handling: Include error messages or status fields in the PagesRecord type for troubleshooting issues.
  • Pagination Support: Extend the CmsPages type to include fields for currentPage, pageSize, and totalPages to handle large datasets effectively.

Step 3: Create the Resolver Model

The Resolver acts as the bridge between the GraphQL schema and the backend logic. It fetches the required data defined in the schema and prepares it for delivery to the frontend.

Purpose

The CmsPages resolver retrieves data for all CMS pages from the database. It leverages Magento's repository patterns for clean and efficient data fetching.

File Creation

Create the file CmsPages.php in the following directory:

app/code/Emmo/CmsPagesGraphQl/Model/Resolver/CmsPages.php

CmsPages.php

PHP Code: CMS Pages GraphQL Resolver

<?php

declare(strict_types=1);

namespace Emmo\CmsPagesGraphQl\Model\Resolver;

use Magento\Framework\Exception\NoSuchEntityException;

use Magento\Framework\GraphQl\Config\Element\Field;

use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;

use Magento\Framework\GraphQl\Query\ResolverInterface;

use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

use Magento\Cms\Api\PageRepositoryInterface;

use Magento\Framework\Api\SearchCriteriaBuilder;

class CmsPages implements ResolverInterface

{

/**

* @var PageRepositoryInterface

*/

private $pageRepository;

/**

* @var SearchCriteriaBuilder

*/

private $searchCriteriaBuilder;

/**

* Constructor

*

* @param PageRepositoryInterface $pageRepository

* @param SearchCriteriaBuilder $searchCriteriaBuilder

*/

public function __construct(

PageRepositoryInterface $pageRepository,

SearchCriteriaBuilder $searchCriteriaBuilder

) {

$this->pageRepository = $pageRepository;

$this->searchCriteriaBuilder = $searchCriteriaBuilder;

}

/**

* Resolve GraphQL request

*

* @param Field $field

* @param mixed $context

* @param ResolveInfo $info

* @param array|null $value

* @param array|null $args

* @return array

* @throws GraphQlNoSuchEntityException

*/

public function resolve(

Field $field,

$context,

ResolveInfo $info,

array $value = null,

array $args = null

): array {

return $this->fetchCmsPages();

}

/**

* Fetch all CMS pages

*

* @return array

* @throws GraphQlNoSuchEntityException

*/

private function fetchCmsPages(): array

{

try {

$searchCriteria = $this->searchCriteriaBuilder

->addFilter('is_active', 1, 'eq') // Fetch only active pages

->create();

$pages = $this->pageRepository->getList($searchCriteria)->getItems();

$cmsPages = [

'allPages' => [],

'totalPages' => count($pages), // Provide the total count of pages

];

foreach ($pages as $page) {

$cmsPages['allPages'][] = [

'identifier' => $page->getIdentifier(),

'name' => $page->getTitle(),

'page_layout' => $page->getPageLayout(),

'content' => $page->getContent(),

'creation_time' => $page->getCreationTime(),

'update_time' => $page->getUpdateTime(),

];

}

return $cmsPages;

} catch (NoSuchEntityException $e) {

throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);

}

}

}

Key Benefits of This Implementation

  • Efficient Data Fetching: Uses Magento's repository pattern and search criteria for optimized database queries.
  • Enhanced Error Handling: Gracefully handles exceptions and provides clear error messages.
  • Flexible Querying: Allows future extensibility for adding more filters or additional data fields.
  • Scalable Design: Prepared for complex GraphQL queries and integrations.

This resolver provides a robust foundation for GraphQL-based interactions with CMS pages, ensuring high performance and maintainability.

Step 4: Install and Test the Module

Once you have created and configured your module, you can proceed to install and test it. Follow these steps to ensure that the module is successfully integrated into your Magento 2 store.

Install the Module

Run the following command to upgrade your Magento setup and install any new modules, including your custom module:

php bin/magento setup:upgrade

This will apply any database schema or data updates related to the module.

Flush Cache

After upgrading the setup, clear the Magento cache to ensure the new module and any changes are recognized:

php bin/magento cache:flush

Test the GraphQL Query

To verify that your GraphQL resolver is working as expected, you can use GraphQL tools like ChromeiQL or Altair to test the query. Here's an example request payload that fetches all CMS pages, including their name, identifier, content, and page layout.

Request Payload:

GraphQL Query

{

cmsPages {

allPages {

name

identifier

content

page_layout

}

}

}

Example Response:

If your module is set up correctly and the CMS pages exist in your Magento store, the response should look something like this:

GraphQL Response

{

"data": {

"cmsPages": {

"allPages": [

{

"name": "404 Not Found",

"identifier": "no-route",

"content": "<dl><dt>...</dt></dl>",

"page_layout": "2columns-right"

},

{

"name": "Home page",

"identifier": "home",

"content": "<p>Homepage content.</p>",

"page_layout": "1column"

}

]

}

}

}

  • name: The title of the CMS page.
  • identifier: The unique identifier for the CMS page.
  • content: The HTML content of the CMS page.
  • page_layout: The layout of the page (e.g., 2columns-right or 1column).

By running this test query and confirming that the response matches the expected data, you can ensure that the GraphQL resolver and the associated CMS page data are correctly integrated into your Magento 2 store.

Essential Tips for GraphQL Developers

When working with GraphQL in Magento, there are several best practices and tips that can help improve the efficiency, flexibility, and debugging of your queries. Here are some key strategies:

1. Implement Custom Conditions in the Resolver

Enhance your query by adding custom filters in the resolver. This allows you to fetch specific products based on various criteria, such as product attributes, categories, or custom fields. For instance, you can filter products by their availability or price range to deliver more targeted data to the client.

2. Expand Your GraphQL Schema

GraphQL schemas are flexible and can be extended to include additional fields. You can add new fields to existing types or create completely new custom types. This expansion allows your GraphQL queries to provide richer and more specific data, improving the user experience for consumers and admins alike.

3. Leverage Magento's Debugging and Logging Tools

Debugging is an essential part of working with GraphQL in Magento. Utilize Magento's built-in logging tools to track errors and troubleshoot issues in your queries. Whether it's a missing field or a failure to fetch data, effective logging can significantly speed up your debugging process.

Summary of Tips

Tip Description
Custom Conditions Add filters in the resolver to fetch specific products based on defined criteria, improving query precision.
Schema Expansion Extend the GraphQL schema by adding new fields or types to meet evolving data requirements.
Debugging Use Magento's logging and debugging tools to troubleshoot errors in GraphQL queries, improving development efficiency.

By incorporating these tips into your development workflow, you can build more powerful, efficient, and maintainable GraphQL queries for your Magento projects.

Tip

To enhance your eCommerce store’s performance with Magento, focus on optimizing site speed by utilizing Emmo themes and extensions. These tools are designed for efficiency, ensuring your website loads quickly and provides a smooth user experience. Start leveraging Emmo's powerful solutions today to boost customer satisfaction and drive sales!

Conclusion

Fetching CMS pages using GraphQL in Magento 2 is a powerful approach that enhances the efficiency and flexibility of managing content on your eCommerce website. With GraphQL, developers can retrieve only the data they need, avoiding the inefficiencies often associated with REST APIs. This means faster loading times, reduced server load, and an overall better user experience for customers.

By querying specific page data such as page name, identifier, layout, and content, developers have greater control over how content is rendered on the frontend. GraphQL enables seamless integration with various frontend frameworks, including React, Vue, or even custom headless applications. The simplicity of querying and handling responses makes it easier to fetch dynamic content without unnecessary overhead.

Moreover, the flexibility of GraphQL makes it a perfect fit for modern web applications, particularly in cases where content needs to be personalized or dynamically loaded. Whether you're building a fully decoupled Magento PWA or enhancing the performance of an existing theme, GraphQL can greatly improve your workflow. By reducing the amount of data transferred between the frontend and backend, you can streamline the user experience, making it faster and more responsive.

For developers, implementing GraphQL in Magento 2 is an opportunity to embrace a modern, efficient API solution that aligns with the growing trend of headless commerce. With minimal setup, easy-to-define queries, and the ability to customize responses, GraphQL is an ideal choice for fetching CMS pages and ensuring your site’s content is served in a high-performance, scalable manner.

In conclusion, integrating GraphQL into your Magento 2 setup for CMS pages opens up new possibilities for improving website performance, scalability, and developer productivity. As the eCommerce landscape continues to evolve, adopting GraphQL will be a critical step toward building future-proof, flexible, and fast websites that meet the needs of both developers and end users.

FAQs

What is GraphQL in Magento 2?

GraphQL is a query language for APIs that enables clients to request exactly the data they need, making it more efficient than traditional REST APIs. Magento 2 supports GraphQL for enhanced data fetching and flexibility.

How do I fetch CMS pages using GraphQL in Magento 2?

To fetch CMS pages using GraphQL, you can use the cmsPages query in your GraphQL request. This will return a list of active CMS pages with data such as name, identifier, content, and page layout.

What data can I retrieve for each CMS page using GraphQL?

You can retrieve the page name, identifier, content, and page layout for each CMS page. This gives you detailed information about the pages on your site.

Can I filter CMS pages by their status in GraphQL?

Yes, you can filter CMS pages by their status using the is_active filter. This ensures that only active pages are retrieved in your query results.

What is the benefit of using GraphQL over REST APIs in Magento 2?

GraphQL provides more efficiency by allowing you to fetch only the data you need. Unlike REST APIs, which return a predefined set of data, GraphQL queries can be tailored to retrieve specific fields, reducing unnecessary data transfers.

What tools can I use to test GraphQL queries in Magento 2?

You can use tools like ChromeiQL or Altair to test and run GraphQL queries. These tools provide an interactive interface to experiment with different queries and see the results immediately.

How do I implement a GraphQL query for fetching CMS pages?

To implement a GraphQL query, you can use the following format: { cmsPages { allPages { name identifier content page_layout } } }. This will return the CMS pages with the specified details.

What is the structure of the response when fetching CMS pages with GraphQL?

The response structure will contain a data key with the cmsPages object, which holds an array of allPages. Each page includes fields such as name, identifier, content, and page_layout.

How do I get the total number of CMS pages using GraphQL?

In the GraphQL response, the total number of CMS pages is provided under the totalPages field. This field contains the count of active pages available in your store.

Can I get CMS page content in a specific format?

Yes, the CMS page content is returned as raw HTML in the response. You can display or process this content as needed on the frontend of your website.

How does GraphQL improve the performance of my Magento store?

GraphQL improves performance by minimizing the amount of data transferred between the server and client. This results in faster load times and better overall performance compared to traditional REST APIs.

Is GraphQL supported in Magento 2 out of the box?

Yes, Magento 2 comes with built-in support for GraphQL, allowing you to query CMS pages and other resources easily without the need for additional configuration or extensions.