Connect to Shopify

Learn how to connect your Shopify data to Retool.

Authentication

This tutorial covers Shopify’s GraphQL API. Shopify also provides a REST API you can connect to Retool, which follows the same general principles.

Note: Retool currently only supports connecting to the Shopify API via our REST API or GraphQL integrations.

Creating a Shopify app

To query your Shopify data via the GraphQL API, you’ll need to create a private app and retrieve your API Key. Shopify uses basic auth for private apps.

To get started, head to your Shopify storefront, and click on “apps” in the left sidebar.

Click on “Manage private apps” and then “Create private app” (If you’ve already created an app, you can skip this step). You may need to enable private app creation in your dashboard if you haven’t already. On the app creation screen, give your app a nice name (“Retool App”) and put in a contact email. You’ll also need to decide on the permission scopes for this app - we’ve given ours read and write permissions for customers, orders, inventory, product listings, and products. You can change all of this information after you create your app, so don’t sweat it too much.

Click “Save”, and you should be redirected to your new app’s settings page. What we’re looking for is the example URL – it should be in the format of https://{apikey}:{password}@{hostname}/admin/api/{version}/graphql.json. Copy that and let’s head into Retool.

Connecting to Retool

Pop open your Retool homepage (or create an account if you don’t have one), and click on the “Resources” tab up top. Tap on the “Create new” button on the top right, and choose “GraphQL” as your resource type. Then, paste your URL into the “Base URL” field. Finally, click “Create resource” and you should be good to go.

Querying data

Getting customers

Let’s display our first 20 customers in a Table component. Start by creating a new query in your query editor (“+ new”) and selecting your Shopify GraphQL API resource from the “Resource” dropdown. This GraphQL query fetches some basic information for the first 20 customers in your Shopify store:

query {
  customers(first: 20) {
    edges {
      node {
        displayName
        email
        defaultAddress {
          name
          address1
          address2
          city
          province
          country
          zip
        }
        ordersCount
      }
    }
  }
}

Click “Preview” to see your results, and make sure to hit “Save and run” to save your results. You can also name the query something descriptive, like getCustomers.

To display this data in a table, drag a new table onto your Retool canvas from the right component sidebar (click on the canvas to bring it up). The data format is a little tricky - click on your new table, head over to the right sidebar (the inspector), and paste this into the “Data” field:

{{ getCustomers.data.customers.edges.map(customer => customer.node) }}

This JavaScript references the .data property of the getCustomers query, destructures two levels deep (.customers.edges) and then maps through each item in the resulting array to pull out the data for each customer.

See below for how to server side paginate this data, so you can see all of your customers in the table.

Getting orders

Let’s display our first 10 orders in a Table component. Start by creating a new query in your query editor (“+ new”) and selecting your Shopify GraphQL API resource from the “Resource” dropdown. This GraphQL query fetches some basic information for the first 10 orders in your Shopify store:

query {
  orders(first: 10) {
    edges {
      node {
        email
        lineItems(first: 10) {
          edges {
            node {
              product {
                title
              }
              quantity
            }
          }
        }
        totalPriceSet {
          shopMoney {
            amount
          }
        }
      }
    }
  }
}

Click “Preview” to see your results, and make sure to hit “Save and run” to save your results. You can also name the query something descriptive, like getOrders.

To display this data in a table, drag a new table onto your Retool canvas from the right component sidebar (click on the canvas to bring it up). The data format is a little tricky - click on your new table, head over to the right sidebar (the inspector), and paste this into the “Data” field:

{{ getOrders.data.orders.edges.map(order => order.node) }}

This JavaScript references the .data property of the getOrders query, destructures two levels deep (.orders.edges) and then maps through each item in the resulting array to pull out the data for each order.

A bunch of the data in the table is nested in objects, which aren’t displaying very nicely - we can parse it out using column mappers. In your table component’s settings, click on the column you want to parse (in our case, Price) and head to the “Mapper” field. You can reference the current column’s value with self, so this is as simple as {{ self.shopMoney.amount }}. You can also rename the column to something more human readable, like Price.

Server side pagination with the Shopify GraphQL API

If you’ve got more than 20 customers and 10 orders (hopefully), these above queries are a bit limiting. Retool supports paginating tables server side, so that you can traverse table pages and automatically rerun queries. You can read the full suite of docs about it here.

Shopify’s GraphQL API supports pagination via a cursor.

  1. Update your query and add variables

First, you’ll need to add a new field to your GraphQL query - the cursor. The Shopify GraphQL API returns this with every edge (in our case - customers) so Retool knows where it is in the data. Then, instead of hardcoding (first: 20), add a few variables. First, for your query root:

($first: Int, $last: Int, $afterPage: String, $beforePage: String)

And then in the customers filter:

(first: $first, last: $last, after: $afterPage, before: $beforePage)

Here’s what the final query should look like:

query ($first: Int, $last: Int, $afterPage: String, $beforePage: String) {
  customers(
    first: $first
    last: $last
    after: $afterPage
    before: $beforePage
  ) {
    edges {
      cursor
      node {
        displayName
        email
        defaultAddress {
          name
          address1
          address2
          city
          province
          country
          zip
        }
        ordersCount
      }
    }
  }
}

Once you add these variables to your GraphQL query in Retool, form fields will appear under your query where you can actually assign values to those variables. Here’s what you’ll need to fill in:

  • first: {{ table1.beforeCursor ? null : table1.pageSize }}
  • last: {{ table1.beforeCursor ? table1.pageSize : null }}
  • afterPage: {{ table1.afterCursor }}
  • beforePage: {{ table1.beforeCursor }}

For more information about the logic behind what’s going on here, refer to our main docs on server side pagination.

  1. Enable server side pagination for your table

Click on your table component, scroll down to the “Pagination” section, and toggle “Server side paginated” to on. From the dropdown, select “GraphQL Relay cursor based.” We need to fill in the three input fields with information about the cursors available.

  • Previous page cursor: {{ _.first(getCustomers.data.customers.edges).cursor }}
  • Next page cursor: {{ _.last(getCustomers.data.customers.edges).cursor }}
  • Whether or not there is more data to load: {{ _.last(getCustomers.data.customers.edges).cursor ? true : false }}

These Lodash functions pull the first and last customers from our query and reference their cursors. Here’s what things should look like:

Voila! Now, clicking through pages in your table actually reruns your query and fetches the correct results from the server.