Drupal Commerce and GraphQL with Apollo and GatsbyJS

Drupal Commerce and GraphQL with Apollo and GatsbyJS

In this post, i wil talk how to create app using Drupal Commerce and Graphql with GatsbyJS & Apollo.

Requirements Drupal

Installation Drupal commerce, more information https://docs.drupalcommerce.org/commerce2/developer-guide/install-update/installation

Installation GraphQL module and eanble GraphQL and GraphQL Core.

Start by configure Drupal Commerce (product, variation, promotion, attributes...) and creating product then visit url localhost:8282/graphql/explorer.

Graphql drupal

With GraphiQL you can run GraphQL queries. It's time to see if we get any product data.Example, to get data for product by Id.

query MyQuery {

  commerceProductById(id: "3") {

    entityId

    entityBundle

    title

    status

    path {

      alias

      pid

      langcode

    }

    ...on CommerceProductDefault{

      body{

        value

      }

      fieldImage{

        url

      }

      stores{

        entity{

          entityLabel

        }

      }

      variations{

        entity{

          ...on CommerceProductVariationDefault{

            fieldPromotion {

              targetPluginConfiguration

            }

            attributeCouleur{

              entity{

                entityLabel

              }

            }

          }

          sku

          price{

            number

            formatted

            currencyCode

          }

        }

      }

    }

  }

}

Finally,we have great result of Graphql.

Graphql

GatsbyJS and React Apollo

Let's start to pull data from Drupal Commerce in the app.we need to install react-apollo, apollo-client, apollo-link-http, apollo-cache-inmemory.

yarn add react-apollo apollo-client apollo-link-http apollo-cache-inmemory

First, create productQuery.js file contain the Graphql query and We can do this using the gql function :

import gql from 'graphql-tag'


export default (id_product) => gql`{

    commerceProductById(id: "${id_product}") {

      entityId

      entityBundle

      title

      status

      path {

        alias

        pid

        langcode

      }

      ...on CommerceProductDefault{

        body{

          value

        }

        fieldImage{

          url

        }

        stores{

          entity{

            entityLabel

          }

        }

        variations{

          entity{

            ...on CommerceProductVariationDefault{

              fieldPromotion {

                targetPluginConfiguration

              }

              attributeCouleur{

                entity{

                  entityLabel

                }

              }

            }

            sku

            price{

              number

              formatted

              currencyCode

            }

          }

        }

      }

    }

}`

Next, we should initialized ApolloClient with the endpoint Drupal api in apolloclient.js.

import { ApolloClient } from 'apollo-client';

import { HttpLink } from 'apollo-link-http';

import { IntrospectionFragmentMatcher, InMemoryCache } from 'apollo-cache-inmemory';


export const graphqlClient = new ApolloClient({

    cache: new InMemoryCache(),

    link: new HttpLink({

        uri: `http://localhost:8282/graphql`

    }),

});

We should include our component in ApolloProvider to can use the HOC returned by graphql to make requests to the GraphQL server using the ApolloClient .

import React, { Component } from 'react'

import { ApolloProvider } from 'react-apollo'

import { graphqlClient } from './apolloClient'

import Product from './product'

const App = (id_product) => (

  <ApolloProvider client={graphqlClient}>

    <Product id_product= {id_product}/>

  </ApolloProvider>

)

export default App

Now, we will use the data in the product component, we can use react-image-gallery to display images of the product

import React, {Fragment} from 'react'

import { Query, ApolloProvider } from 'react-apollo'

import productQuery from './productQuery'

import { graphqlClient } from './apolloClient'

import ImageGallery from 'react-image-gallery'

import "react-image-gallery/styles/css/image-gallery.css"

const Product = ({props}) => {
  const {productId} = props.match.params
  const images = data.commerceProductById.fieldImage
        ? data.commerceProductById.fieldImage.map(image => ({
            original: image.url,
            thumbnail: image.url,
          }))
        : [];
  return (
          <div className="product-detail" >
                <Query query={productQuery(productId)}>
                  {({loading, error, data}) => {
                    if (loading) return <div className={`col-sm-12`} key={`loading`}>Loading...</div>
                    if (error) return <div key={`error`}>Error! ${error.message}</div>
                    if (data) {
                        return (
                            <Fragment>
                               <div className="images">
                                <ImageGallery items={images} 
                                 thumbnailPosition="bottom" 
                                 showPlayButton={false}  
                                 lazyLoad 
                               />
                          </div>
                          <div className="detail-item">
                            <h1>{ data.commerceProductById.title }</h1>
                            <div dangerouslySetInnerHTML={{ __html: data.commerceProductById.body.value }} />
                            {data.commerceProductById.variations[0].entity.price.formatted}
                         </div>
                    </Fragment>
                      )
                      }
                 }
            }
              </Query>
          </div>
  )
} 
export default Product

Finally, we have a product page using Drupal Commerce and GraphQL with React & Apollo in GtasbyJS project.

 

Comments