Using GraphQL to Unlock eCommerce Data for Frontend Teams

“While the data layer space is still in constant movement, one thing seems clear: GraphQL and its related technologies are here to stay.” State of JS 2020 Survey

Anant Jhingran
Anant Jhingran
Jun 9, 2021
Using GraphQL to Unlock eCommerce Data for Frontend Teams

“While the data layer space is still in constant movement, one thing seems clear: GraphQL and its related technologies are here to stay.” State of JS 2020 Survey

This is the first of two blog posts in which we’ll explore how GraphQL is an important enabling technology for eCommerce. The eCommerce ecosystem stands to gain speed and productivity by the adoption of GraphQL at a time when the mandate for businesses to provide engaging customer experiences was never more profound.

The eCommerce landscape in 2021

eCommerce sales have been on the rise. In the US alone, consumer online spend in 2020 was up an incredible 44.0% year over year, according to Digital Commerce 360 estimates. It was the highest annual U.S. eCommerce growth in at least two decades, and nearly triple the 15.1% jump in 2019.

Online merchants seek higher levels of flexibility and control, and speed is more important than ever - speed of delivering new experiences and speed of customer conversion. Headless commerce is growing in popularity, and for brands of all sizes, it can provide more ecommerce platform options and enable them to decouple the front-end applications from backend data sources.

A dizzying array of backends power modern businesses — CRMs, CMSs, databases, 1st and 3rd party APIs and services, inventory and product management systems, recommendation engines — to name a few. And backend data sources only grow in number and complexity as more businesses up their digital experience game. For example, typical eCommerce websites pull in data from at least half a dozen backends:

  • A core eCommerce system like Shopify, BigCommerce, or popular Jamstack backends like Snipcart, which are typically operated by the eCommerce team
  • A core CMS like AgilityCMS, Contentful etc., typically managed by the marketing team
  • A set of logistics endpoints such as FedEx, UPS, or a myriad shipping and delivery services
  • An inventory management system
  • Email, CRM and other marketing automation systems like Hubspot, Mailchimp, Klaviyo and so on
  • A recommendation system
  • The list goes on...

GraphQL APIs: Simplify data access and accelerate app development

GraphQL APIs help abstract the complexities of multiple backends behind a unified endpoint. Front-end developers benefit because they can fetch data from the multiple backends with a single query to the GraphQL endpoint.

In this blog, we describe how you can build a GraphQL API that easily connects two important systems in an eCommerce stack. The systems we are connecting through our GraphQL endpoint are the Shopify eCommerce platform and the Agility CMS content management system.

GraphQL APIs

Connecting the Agility CMS with Shopify

Thanks to Joel Varty and team at Agility CMS for challenging us to crack this important scenario. Here we connect just two systems and in two different ways. It’s not difficult to see how complexity is compounded when additional integrations are needed between any two components and then new connections are required for each additional component of your eCommerce ecosystem. We believe that this can serve as a scalable foundation for your eCommerce ecosystem.

We use the Agility CMS for all our product “copy”: titles, descriptions, and images. We also use Agility to associate products with things like categories and target audiences. We’ll keep track of prices and product variants in the Shopify eCommerce platform.

The connections

We’ll look at just two integrations to connect our core systems. The first is to retrieve product information from both systems in one API. The second is a synchronization process — when a new product is added in Shopify, a record is created in Agility, so that the marketing team can get to work with descriptions, categorizations, and so on.

Now, you could build some of your integration logic into your front-end application(s). But that’s a lot of logic to write and maintain, is brittle and fraught with risk, and raises more than a few security questions. You could also build this integration into a back-end service.

But then, not only are you maintaining your eCommerce site, but you’re the proud new owner of a backend service — essentially an IT product. You’re on the hook for all the care and feeding that goes into building and maintaining an IT product. It’s not a small task.

GraphQL as the solution

The GraphQL API you build in StepZen is an API of APIs - different backends, authorizations, response protocols, syntax and more are made uniform in the context of your GraphQL API.

So GraphQL is a good solution because it lets you abstract the complexities of backends and power your apps with the data they need from multiple backends with a single query.

StepZen is a fully managed service that makes it easy to build GraphQL APIs and connect data from REST, GraphQL, databases, or any backend. Furthermore, we secure the API, host and manage the service so that you can speed app development while maintaining security and control of your data. You have no servers to manage, no code to write to parallelize execution, ensure keys and queries are secure, and the cache is handled by StepZen.

Let’s look at some code

Let’s look at what it takes to combine the results from the Shopify API with the Agility API when we want to retrieve a product listing.

StepZen’s configuration-driven approach means that we don’t need to program the integration logic. Instead, we configure our GraphQL schema and therein specify how StepZen talks to the various backend systems and links data together.

Retrieving and linking data from multiple systems

In our example scenario, with the product data coming from both Shopify and Agility, we define a product type in our GraphQL schema that looks like this:

type Product {

  title: String

  description: String

  image: String

  createdAt: String

  agilityId: ID!

  admin_graphql_api_id: String

  hero: Boolean

  type: String

  use: String

  price: String

  shopifyId: ID!

  audience: String

  variants: [ShopifyProductVariants]

    @materializer(

      query: "shopifyProductVariants"

      arguments: [{ name: "product_id", field: "shopifyId" }]

    )

  images: [ShopifyProductImages]

    @materializer(

      query: "shopifyProductImages"

      arguments: [{ name: "product_id", field: "shopifyId" }]

    )

  options: [ShopifyProductOptions]

    @materializer(

      query: "shopifyProductOptions"

      arguments: [{ name: "product_id", field: "shopifyId" }]

    )

}

This is mostly straightforward GraphQL Schema Definition Language (SDL), but those familiar with SDL will notice a custom directive, @materializer. This tells StepZen how to retrieve elements for a type using queries defined elsewhere in the schema. (For more on @materializer, see the docs.)

And one of those queries looks like this:

type Query {

  shopifyProductVariants(shopifyId: ID!): [ShopifyProductVariants]

    @rest(

      endpoint: "https://$store_name.myshopify.com/admin/api/2021-04/products/$shopifyId;.json"

      resultroot: "product.variants[]"

      configuration: "shopify_config"

    )

}

Here we see another StepZen custom directive, @rest, which tells StepZen how to use Shopify’s REST API to retrieve variants given a product ID.

We can define a similar query to retrieve data from Agility, given a product ID. Notice the list of directive setters that rename fields from Agility to match the Product Type fields that we specified earlier.

agilityProduct(agilityId: ID!): AgilityProduct

    @rest(

      endpoint: "https://$instance;-api.agilitycms.cloud/preview/en-us/item/$agilityId"

      configuration: "agility_config"

      setters: [

        { field: "audience", path: "fields.audience" }

        { field: "description", path: "fields.description" }

        { field: "createdAt", path: "properties.modified" }

        { field: "agilityId", path: "contentID" }

        { field: "image", path: "fields.image" }

        { field: "hero", path: "fields.hero" }

        { field: "type", path: "fields.type" }

        { field: "use", path: "fields.use" }

      ]

    )

So with a simple GraphQL schema, we’ve configured a single GraphQL API that we can use to retrieve product data from both Agility and Shopify. Now our front-end developers don’t need to be concerned with how to retrieve data from any backend system we work with. They can run a single query for a product and pull some data from Shopify and some from Agility.

Better still, if we need to change from Shopify to another eCommerce provider, we simply change the StepZen configuration. The frontend site or app doesn’t need to change or know about the specific backend systems that provide the data for the Product Type.

Synchronizing data between systems

Now what about synchronizing data between systems? When our product team creates a new product in Shopify, we want our marketing team to see the correct information in Agility. We can address this with the same GraphQL API we build to support our eCommerce site, ensuring that we keep everything in sync for our backend and frontend developers. To do this we take advantage of Shopify’s web hook capability, and instruct our Shopify store to call a StepZen API whenever a new product is created.

This Shopify web hook executes a ‘Mutation’ on the StepZen GraphQL endpoint like so:

 shopifyToAgilitySequence(

    title: String!

    description: String!

    shopifyId: ID!

    image: String!

  ): [Map]

    @sequence(

      steps: [

        { mutation: "shopifyToAgility" }

        { mutation: "shopifyToAgilityMap" }

      ]

    )

A custom StepZen directive called @sequence executes two mutations in sequence.

  1. When Shopify calls the webhook endpoint, the shopifyToAgilitySequence executes the initial mutation, shopifyToAgility, to provide all the product “copy” to the Agility CMS. We will later query this data to power our NextJS frontend application.
  2. The data written to AgilityCMS is accessible for our content team to create and manage content from either platform. All the import and synchronization tasks are automated for us.
  3. The second mutation, shopifyToAgilityMap is executed to map the product shopifyId generated from the initial web hook to the new Agility product that was created in the mutation, shopifyToAgility.
  4. shopifyToAgilityMap writes to a custom content model in AgilityCMS to ensure all Agility product data is synced with the Shopify product data via id mapping.
  5. @sequence executes in real time to allow fields of the previous mutation (shopifyToAgility) to immediately be used as arguments to the subsequent mutation (shopifyToAgilityMap) in the sequence.
  6. After shopifyToAgilitySequence finishes running the steps of the sequence, there is one product created in two platforms, Shopify and AgilityCMS, tied together by id mapping, ready for staging on the frontend application.

Recap

We’ve looked at how to build a GraphQL API that can retrieve and link data from multiple eCommerce systems and also synchronize data between systems – just two ways of combining data from core eCommerce systems.

Whatever systems you start with, the list is bound to grow, as you continuously evolve your customers’ experiences. As eCommerce companies look for ways to bring systems (and data) together and future proof their infrastructure, GraphQL offers an important solution. Using a unified, managed GraphQL API, we can eliminate the need for developers to build and maintain a costly and likely complex set of integrations as your systems scale. It enables backends to be abstracted behind a single easy-to-query endpoint, unlocking the data your front-end teams need to deliver experiences at speed. Backend teams can maintain control of the data, and add more queries and types as market and customer needs evolve, but the core foundation remains constant.

We’ve shown you how through configuring your GraphQL SDL, and a few custom GraphQL directives, you can easily connect and link any backend data. You can easily expand to connect additional backends or configure new backends if providers change, without requiring rework of the front-end app. At runtime, you don’t build or manage a GraphQL server, worry if backends are down or the response from one has changed. You don’t have to make tradeoffs between adding a cache or changing logic or myriad other concerns to run and maintain your code effectively.

Where to go from here

I am looking forward to joining Agility’s Joel Varty in this Developer Workshop on July 8 2021 > Power up your Jamstack with GraphQL and Headless CMS. We’ll explore this solution in detail. Please join us - it’s going to be fun and we look forward to your feedback and questions.

 

StepZen is a fully managed service that enables developers to easily build aGraphQL API for REST, GraphQL, databases, or any backend. Try it Free > stepzen.com 

Check out this Webinar on GraphQL!

Get Access Now

Power up your Jamstack with GraphQL and Headless CMS
Back to All Articles

Our Latest Posts