Connecting the dots: Shopify meets Softr with REST API integration


Introduction
Recently I wrote a blog post about REST APIs in Softr, a powerful No Code tool. We saw how to integrate Spoonacular with Softr and built a fun app.
In this post, let’s look at integrating Shopify, one of the most powerful commerce platforms with Softr to build an internal tool that can be used by Customer support agents. Yes, with the help of REST APIs to fetch a good number of details using Shopify’s APIs and supplementing them in a Softr app.
The reason to take up this example is twofold:
Learning to integrate two powerful platforms is a win-win for anyone
I always try to explain any concept with a real world use case. From my personal experience, I find it easy to pick up anything new when it has something that I can resonate with. Or, when it has a practical use rather than a foo bar type of an analogy. It’s just a personal preference ☺
I shall focus more on Transformer while building the REST API process, as that makes the whole integration a game changer as far as Softr is concerned. If this is your first time trying to integrate a REST API with Softr, I’d recommend reading my previous post or check Softr’s documentation on REST API integration.
This post is intended for someone who is quite comfortable setting up a Shopify store. If you are completely new to Shopify, I’d highly recommend spending time on Shopify Academy.
Let’s dive right in!
For the moment, let’s assume you are a Shopify store owner who has multiple stores. Your business is picking up and orders are increasing. So are customer queries. You decide to outsource customer support. All that the customer support team needs to know is your store details, the products you sell, the orders placed, their shipping and tracking details, return options and so on.
So you decide to build a Softr app that has a primary data source (let’s use AirTable to keep things simple) to add/modify/delete details about Customer support agents, designing their access and roles. The information that comes from Shopify will be read-only to these agents. In order to bring those details, we use the REST API.
Since this post is more about integration, I’m skipping the entire step of creating a Shopify store, adding products and all other related steps. Here’s a brilliant video from Shopify on getting started with Shopify.
Let’s now move on to the AirTable part.
Heads up, I’m not planning to delve deep into AirTable as that’s out of scope for this post. A few basic definitions:
What is AirTable?
It is a visual development tool to create and maintain databases. It can do much more than the database part though, one can create automation, create reports, in fact one can build custom apps too. Originally, they started as a database though with the No Code approach.
If you are a beginner with AirTable, here’s a good video tutorial. If you like to read rather than watch, here’s a real good one from the Zapier blog.
I created a Base in my AirTable account and named it Shopify Base. To get started, I added two tables, Users and Stores.
Users table will hold the employee details of the fictitious Customer Success organization.
Stores table holds the Shopify Store details at a restricted level. For the sake of simplicity, let’s assume an agent takes care of queries related a single store.
For now, let’s pause here as far as AirTable is concerned.
Let’s now move on to Softr part.
Sign up/Log in to Softr as the first step
From the dashboard, click on Data sources - Connect data source
Choose REST API BETA as the data source and click on Continue
Choose Shopify and click on Continue
Here’s a good link that talks in detail about generating API access token. I did that and set the value up. Click on Continue to set up the APIs.
By default, Softr provides a resource to list the products. Click on the 3 dots and edit it in order to add your store name and other parameters.
Here’s the GET URL to list the products from our Shopify store
https://pasteltshirts.myshopify.com/admin/api/2024-10/products.json
Under the URL are 5 tabs, Headers, URL parameters, Placeholders, Pagination and Transformer. I wrote a piece of Javascript code to fetch a subset of details from products.json in the Transformer tab. The original response has a lot many things.
Here’s the link to the doc on Shopify’s product API, don’t forget to check out the amount of information that comes as response.
Breaking Down the Process of Building a Transformer
As I mentioned in the Introduction section, one of the primary objectives of this post is decoding the transformer function as much as we can. Let’s get started with that!
The Transformer tab is where we can write vanilla javascript code to filter, apply decoration to the output, provide default values and more to the response that any API returns.
By filter, the user can pick and choose what details they’d want to see from the enormous set of information that comes back as response.
By decoration to the output, the user can decide the formatting of each field, eg., currency fields can be prefixed with a $ sign, amount can have commas in the way we define, date fields can be formatted in the way that’s appropriate to the business.
By default, the user can define what values should be displayed if the response returns a null value. A typical example would be to display NA instead of showing a blank.
Since Shopify & Softr are visual development tools and majority of end users may not come from a typical programming background, let’s take the help of AI to write these transformers.
There are a variety of tools in the market that are brilliant when it comes to conversational search engines, ChatGPT from OpenAI, Perplexity, Claude from Anthropic, Gemini from Google, to name a few. I’m sure you may have used a few of these in the past, even otherwise they are amazingly simple but incredibly powerful.
Just pick one, sign up and start giving prompts aka ask questions, simple huh 🤓
For the purpose of this blog, I choose Perplexity. I already have an account there and I’m on the free plan. This is how the home page looks like 👇
Now we can start to ask questions. Before that, let’s refresh our memory on the Product list API from Shopify and what response does it return by default.
Here’s the GET API to fetch the list of products for my store:
https://pasteltshirts.myshopify.com/admin/api/2024-10/products.json
And here’s the default response from my store:
{
"products": [
{
"id": 7656520220735,
"title": "Blue pastel shade T-shirts for young boys",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"vendor": "Sam's Tshirts",
"product_type": "Cotton T-shirts",
"created_at": "2024-12-01T15:31:47+05:30",
"handle": "blue-pastel-shade-t-shirts-for-young-boys",
"updated_at": "2024-12-03T07:12:57+05:30",
"published_at": "2024-12-01T15:31:47+05:30",
"template_suffix": "",
"published_scope": "global",
"tags": "blue, organic cotton, pastel shades, short sleeves",
"status": "active",
"admin_graphql_api_id": "gid://shopify/Product/7656520220735",
"variants": [
{
"id": 41332581236799,
"product_id": 7656520220735,
"title": "Default Title",
"price": "399.00",
"position": 2,
"inventory_policy": "deny",
"compare_at_price": "599.00",
"option1": "Default Title",
"option2": null,
"option3": null,
"created_at": "2024-12-01T15:31:47+05:30",
"updated_at": "2024-12-01T15:38:30+05:30",
"taxable": true,
"barcode": null,
"fulfillment_service": "manual",
"grams": 0,
"inventory_management": "shopify",
"requires_shipping": true,
"sku": "100",
"weight": 0.25,
"weight_unit": "g",
"inventory_item_id": 43432046264383,
"inventory_quantity": 20,
"old_inventory_quantity": 20,
"admin_graphql_api_id": "gid://shopify/ProductVariant/41332581236799",
"image_id": null
}
],
"options": [
{
"id": 9868884869183,
"product_id": 7656520220735,
"name": "Title",
"position": 1,
"values": [
"Default Title"
]
}
],
"images": [
{
"id": 32761238519871,
"alt": null,
"position": 1,
"product_id": 7656520220735,
"created_at": "2024-12-01T15:35:28+05:30",
"updated_at": "2024-12-01T15:35:30+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761238519871",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_0.jpg?v=1733047530",
"variant_ids": []
},
{
"id": 32761238454335,
"alt": null,
"position": 2,
"product_id": 7656520220735,
"created_at": "2024-12-01T15:35:28+05:30",
"updated_at": "2024-12-01T15:35:30+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761238454335",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_1.jpg?v=1733047530",
"variant_ids": []
},
{
"id": 32761238487103,
"alt": null,
"position": 3,
"product_id": 7656520220735,
"created_at": "2024-12-01T15:35:28+05:30",
"updated_at": "2024-12-01T15:35:30+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761238487103",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_3.jpg?v=1733047530",
"variant_ids": []
}
],
"image": {
"id": 32761238519871,
"alt": null,
"position": 1,
"product_id": 7656520220735,
"created_at": "2024-12-01T15:35:28+05:30",
"updated_at": "2024-12-01T15:35:30+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761238519871",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_0.jpg?v=1733047530",
"variant_ids": []
}
},
{
"id": 7656519860287,
"title": "Green pastel shade T-shirts for young girls",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"vendor": "Sam's Tshirts",
"product_type": "Cotton T-shirts",
"created_at": "2024-12-01T15:30:52+05:30",
"handle": "green-pastel-shade-t-shirts-for-young-girls",
"updated_at": "2024-12-03T15:13:28+05:30",
"published_at": "2024-12-01T15:30:52+05:30",
"template_suffix": "",
"published_scope": "global",
"tags": "green, organic cotton, pastel shades, short sleeves",
"status": "active",
"admin_graphql_api_id": "gid://shopify/Product/7656519860287",
"variants": [
{
"id": 41332581171263,
"product_id": 7656519860287,
"title": "Default Title",
"price": "399.00",
"position": 2,
"inventory_policy": "deny",
"compare_at_price": "599.00",
"option1": "Default Title",
"option2": null,
"option3": null,
"created_at": "2024-12-01T15:30:53+05:30",
"updated_at": "2024-12-01T15:39:11+05:30",
"taxable": true,
"barcode": "",
"fulfillment_service": "manual",
"grams": 0,
"inventory_management": "shopify",
"requires_shipping": true,
"sku": "50",
"weight": 0.25,
"weight_unit": "g",
"inventory_item_id": 43432046198847,
"inventory_quantity": 75,
"old_inventory_quantity": 75,
"admin_graphql_api_id": "gid://shopify/ProductVariant/41332581171263",
"image_id": null
}
],
"options": [
{
"id": 9868884213823,
"product_id": 7656519860287,
"name": "Title",
"position": 1,
"values": [
"Default Title"
]
}
],
"images": [
{
"id": 32761234096191,
"alt": null,
"position": 1,
"product_id": 7656519860287,
"created_at": "2024-12-01T15:29:59+05:30",
"updated_at": "2024-12-01T15:32:15+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761234096191",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_0.jpg?v=1733047200",
"variant_ids": []
},
{
"id": 32761234128959,
"alt": null,
"position": 2,
"product_id": 7656519860287,
"created_at": "2024-12-01T15:29:59+05:30",
"updated_at": "2024-12-01T15:32:15+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761234128959",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_1.jpg?v=1733047200",
"variant_ids": []
},
{
"id": 32761234161727,
"alt": null,
"position": 3,
"product_id": 7656519860287,
"created_at": "2024-12-01T15:29:59+05:30",
"updated_at": "2024-12-01T15:32:15+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761234161727",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_2.jpg?v=1733047200",
"variant_ids": []
},
{
"id": 32761234194495,
"alt": null,
"position": 4,
"product_id": 7656519860287,
"created_at": "2024-12-01T15:29:59+05:30",
"updated_at": "2024-12-01T15:32:15+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761234194495",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_3.jpg?v=1733047200",
"variant_ids": []
}
],
"image": {
"id": 32761234096191,
"alt": null,
"position": 1,
"product_id": 7656519860287,
"created_at": "2024-12-01T15:29:59+05:30",
"updated_at": "2024-12-01T15:32:15+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32761234096191",
"width": 1120,
"height": 1120,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_0.jpg?v=1733047200",
"variant_ids": []
}
},
{
"id": 7649742520383,
"title": "Pastel colored short sleeve t-shirt",
"body_html": "<p>Experience ultimate comfort and style with our Pastel Colored Short Sleeve T-Shirt. Made with organic cotton, it offers a soft and durable fit that's worth the cost. Embrace the trendy pastel colors and enjoy the comfort fit all day long.</p>",
"vendor": "My Store",
"product_type": "Cotton T-shirts",
"created_at": "2024-11-23T19:33:29+05:30",
"handle": "pastel-colored-short-sleeve-t-shirt",
"updated_at": "2024-12-03T15:16:16+05:30",
"published_at": "2024-11-23T19:33:29+05:30",
"template_suffix": "",
"published_scope": "global",
"tags": "organic cotton, pastel shades, peach, short sleeves",
"status": "active",
"admin_graphql_api_id": "gid://shopify/Product/7649742520383",
"variants": [
{
"id": 41320538636351,
"product_id": 7649742520383,
"title": "Default Title",
"price": "499.00",
"position": 2,
"inventory_policy": "deny",
"compare_at_price": "699.00",
"option1": "Default Title",
"option2": null,
"option3": null,
"created_at": "2024-11-23T19:33:31+05:30",
"updated_at": "2024-12-01T15:20:55+05:30",
"taxable": true,
"barcode": "",
"fulfillment_service": "manual",
"grams": 0,
"inventory_management": "shopify",
"requires_shipping": true,
"sku": "",
"weight": 0.3,
"weight_unit": "g",
"inventory_item_id": 43419568603199,
"inventory_quantity": 98,
"old_inventory_quantity": 98,
"admin_graphql_api_id": "gid://shopify/ProductVariant/41320538636351",
"image_id": null
}
],
"options": [
{
"id": 9860502552639,
"product_id": 7649742520383,
"name": "Title",
"position": 1,
"values": [
"Default Title"
]
}
],
"images": [
{
"id": 32716789481535,
"alt": null,
"position": 1,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:29:58+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789481535",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__candid-image-photography-natural-textures-highly-r__31992.jpg?v=1732370399",
"variant_ids": []
},
{
"id": 32716789514303,
"alt": null,
"position": 2,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:30:29+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789514303",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31995.jpg?v=1732370431",
"variant_ids": []
},
{
"id": 32716789547071,
"alt": null,
"position": 3,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:30:36+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789547071",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31996.jpg?v=1732370438",
"variant_ids": []
},
{
"id": 32716789579839,
"alt": null,
"position": 4,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:30:41+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789579839",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31997.jpg?v=1732370442",
"variant_ids": []
},
{
"id": 32716789612607,
"alt": null,
"position": 5,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:30:47+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789612607",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31998.jpg?v=1732370448",
"variant_ids": []
},
{
"id": 32716789645375,
"alt": null,
"position": 6,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:30:51+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789645375",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__candid-image-photography-natural-textures-highly-r__31993.jpg?v=1732370452",
"variant_ids": []
}
],
"image": {
"id": 32716789481535,
"alt": null,
"position": 1,
"product_id": 7649742520383,
"created_at": "2024-11-23T19:29:58+05:30",
"updated_at": "2024-11-23T19:33:29+05:30",
"admin_graphql_api_id": "gid://shopify/ProductImage/32716789481535",
"width": 896,
"height": 1152,
"src": "https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__candid-image-photography-natural-textures-highly-r__31992.jpg?v=1732370399",
"variant_ids": []
}
}
]
}
I just have 3 products and the length of response is already multiple pages long 🙄. Here’s how I approach fine-tuning my response
Spend some time analyzing the default response. Make a note of the fields that are strings, those that are arrays, sometimes it might be array inside an array. Pay attention to those!
Pick out the fields that might be of interest to your end user
Once you decide, try to ask the AI to write a piece of javascript that returns the fields you want
What I usually do, the first time I choose simple variables so that it’ll be easy to understand what the AI generates
In our case, let’s choose the fields title, body_html and status to start with
Go back to Perplexity and try giving a prompt so that it returns what we want. This is what I gave 👇
Below is the code that Perplexity generated when I gave the above prompt 👇
async function fetchProducts() {
const endpoint = 'https://your-store-name.myshopify.com/admin/api/2024-07/products.json'; // Update with your store name and API version
const headers = {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'your_access_token' // Your API access token
};
try {
const response = await fetch(endpoint, { method: 'GET', headers });
const data = await response.json();
// Extracting required fields from each product
return data.products.map(product => ({
id: product.id,
title: product.title,
body_html: product.body_html,
status: product.status
}));
} catch (error) {
console.error('Error fetching products:', error);
}
}
Let’s go through line by line:
async function fetchProducts() {
It defines a function with the name fetchProducts
const endpoint = 'https://your-store-name.myshopify.com/admin/api/2024-07/products.json'; // Update with your store name and API version
It then defines the GET Products API as a constant with the name endpoint
const headers = {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'your_access_token' // Your API access token
};
It then defines two header variables, Content-Type and X-Shopify-Access-Token and stored under the name headers which is also a constant
We do not need these constants as part of the Transformer as we define these in Softr portal directly while we configure the API.
Now you make ask why did it generate inspite of telling not to add header related information. Probably we need to rework on our prompt. An alternative is to just take what we need from what it generates.
Let’s move on:
try {
const response = await fetch(endpoint, { method: 'GET', headers });
const data = await response.json();
// Extracting required fields from each product
return data.products.map(product => ({
id: product.id,
title: product.title,
body_html: product.body_html,
status: product.status
}));
} catch (error) {
console.error('Error fetching products:', error);
}
This is a try-catch block. The code inside the try block will be executed by default, if an error/exception is thrown, then the code inside the catch block will fire. In this case, the error will be logged to the console.
Alright, let’s take a quick look inside the try block.
const response = await fetch(endpoint, { method: 'GET', headers });
This invokes the endpoint, along with the type of HTTP method along with header parameters.
const data = await response.json();
The variable data holds the response in JSON format.
Now comes the part that we are interested in 😎
// Extracting required fields from each product
return data.products.map(product => ({
id: product.id,
title: product.title,
body_html: product.body_html,
status: product.status
}));
This is the piece of code that we really need as far as Softr’s Transformer is concerned.
Let’s just copy paste the above code with just one change and paste it in our Transformer tab. What’s the change?
In the above code, it reads as data.products as the response was stored in a variable called data.
In Softr’s case, it is enough if you give as response.products.map(…
Shall we paste and execute to see what happens?
Click on Execute and this is what I see in the Schema tab 👇
In the Transformed JSON tab, this is the output I see 👇
[
{
"id": 7656520220735,
"title": "Blue pastel shade T-shirts for young boys",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"status": "active"
},
{
"id": 7656519860287,
"title": "Green pastel shade T-shirts for young girls",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"status": "active"
},
{
"id": 7649742520383,
"title": "Pastel colored short sleeve t-shirt",
"body_html": "<p>Experience ultimate comfort and style with our Pastel Colored Short Sleeve T-Shirt. Made with organic cotton, it offers a soft and durable fit that's worth the cost. Embrace the trendy pastel colors and enjoy the comfort fit all day long.</p>",
"status": "active"
}
]
Cool, huh? 😎
Alright, let’s try something else. If the status is active, let’s ask AI to display as “available”. Let’s go and modify the prompt a bit and see what happens.
Here is the modified prompt.
And see the code it generated 👇
async function fetchProductDetails() {
const response = await fetch('https://your-store.myshopify.com/admin/api/2024-07/products.json', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'your_access_token'
}
});
const data = await response.json();
const products = data.products;
return products.map(product => ({
id: product.id,
title: product.title,
body_html: product.body_html,
status: product.status === 'active' ? 'available' : product.status
}));
}
I then copy/pasted (don’t forget to change to response.products in the return statement) in Softr’s Transformer tab and clicked on Execute. Here’s the response 👇
[
{
"id": 7656520220735,
"title": "Blue pastel shade T-shirts for young boys",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"status": "available"
},
{
"id": 7656519860287,
"title": "Green pastel shade T-shirts for young girls",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"status": "available"
},
{
"id": 7649742520383,
"title": "Pastel colored short sleeve t-shirt",
"body_html": "<p>Experience ultimate comfort and style with our Pastel Colored Short Sleeve T-Shirt. Made with organic cotton, it offers a soft and durable fit that's worth the cost. Embrace the trendy pastel colors and enjoy the comfort fit all day long.</p>",
"status": "available"
}
]
Isn’t it easy? 😁. Alright, let’s try adding a few more to the response and then try to apply some sort of transformation.
Here’s my latest prompt that I gave in Perplexity
Here is the code it generated 👇
async function fetchProductDetails() {
const response = await fetch('https://your-store.myshopify.com/admin/api/2024-07/products.json', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'your_access_token'
}
});
const data = await response.json();
const products = data.products;
return products.map(product => ({
id: product.id,
title: product.title,
body_html: product.body_html,
product_type: product.product_type.includes("Cotton") ? "cotton" : product.product_type,
published_at: new Date(product.published_at).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
}));
}
I now took the return statement and pasted in Softr’s Transformer tab and below is the output 👇
[
{
"id": 7656520220735,
"title": "Blue pastel shade T-shirts for young boys",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"status": "available",
"product_type": "cotton",
"published_at": "December 1, 2024"
},
{
"id": 7656519860287,
"title": "Green pastel shade T-shirts for young girls",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"status": "available",
"product_type": "cotton",
"published_at": "December 1, 2024"
},
{
"id": 7649742520383,
"title": "Pastel colored short sleeve t-shirt",
"body_html": "<p>Experience ultimate comfort and style with our Pastel Colored Short Sleeve T-Shirt. Made with organic cotton, it offers a soft and durable fit that's worth the cost. Embrace the trendy pastel colors and enjoy the comfort fit all day long.</p>",
"status": "available",
"product_type": "cotton",
"published_at": "November 23, 2024"
}
]
I hope this gave a fair idea on how to use AI to generate the transformer code. It’s just a matter of modifying the prompt until you get your desired output.
Let’s now execute the final transformer code
This is my final transformer code that I used in my Softr app 👇
return response.products.map(product=> {
return {
id: product.id,
title:product.title,
body_html: product.body_html,
price: product.price,
weight: product.weight,
product_type: product.product_type,
tags: product.tags ? product.tags.split(',').map(tag => tag.trim()) : [],
vendor: product.vendor,
price: product.variants[0].price,
images: product.images.map(image => image.src),
available_quantity: product.variants[0].inventory_quantity,
}
});
When i click on Execute, under Transformed JSON tab, I see this:
[
{
"id": 7656520220735,
"title": "Blue pastel shade T-shirts for young boys",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"price": "399.00",
"product_type": "Cotton T-shirts",
"tags": [
"blue",
"organic cotton",
"pastel shades",
"short sleeves"
],
"vendor": "Sam's Tshirts",
"images": [
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_0.jpg?v=1733047530",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_1.jpg?v=1733047530",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_professionally_lit_and_styled_photograph_of_3.jpg?v=1733047530"
],
"available_quantity": 20
},
{
"id": 7656519860287,
"title": "Green pastel shade T-shirts for young girls",
"body_html": "<p>Experience true comfort and sustainability with our green pastel shade T-shirts for young girls. Made from organic cotton with a soft, durable fabric, these shirts provide a comfortable fit and peace of mind for eco-conscious families. Upgrade your child's wardrobe with our environmentally-friendly fashion.</p>",
"price": "399.00",
"product_type": "Cotton T-shirts",
"tags": [
"green",
"organic cotton",
"pastel shades",
"short sleeves"
],
"vendor": "Sam's Tshirts",
"images": [
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_0.jpg?v=1733047200",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_1.jpg?v=1733047200",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_2.jpg?v=1733047200",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/Leonardo_Phoenix_A_vibrant_and_professionally_lit_photograph_f_3.jpg?v=1733047200"
],
"available_quantity": 75
},
{
"id": 7649742520383,
"title": "Pastel colored short sleeve t-shirt",
"body_html": "<p>Experience ultimate comfort and style with our Pastel Colored Short Sleeve T-Shirt. Made with organic cotton, it offers a soft and durable fit that's worth the cost. Embrace the trendy pastel colors and enjoy the comfort fit all day long.</p>",
"price": "499.00",
"product_type": "Cotton T-shirts",
"tags": [
"organic cotton",
"pastel shades",
"peach",
"short sleeves"
],
"vendor": "My Store",
"images": [
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__candid-image-photography-natural-textures-highly-r__31992.jpg?v=1732370399",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31995.jpg?v=1732370431",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31996.jpg?v=1732370438",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31997.jpg?v=1732370442",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__short-sleeve-tshirts-in-pastel-colors__31998.jpg?v=1732370448",
"https://cdn.shopify.com/s/files/1/0588/6355/0527/files/freepik__candid-image-photography-natural-textures-highly-r__31993.jpg?v=1732370452"
],
"available_quantity": 98
}
]
- We need the id column as this is the handle to navigate to the corresponding detail page where we can show a lot more information about a product.
Time to build the Softr app
Now that we’ve set one resource, let’s start to build a Softr app and make use of this information.
Navigate to the Home page and click on Start from scratch block that shows on the top.
In the next page, you need to choose your Data Source. I chose AirTable and the Shopify Base that we created in the earlier step.
Softr generates a good number of pages by default. I added two more, Product and Product details.
I then added a Block - Grid as the purpose is to show the products in a Store.
In the Source tab, I selected the Shopify REST API as my data source and Products as Resource
In the content tab, it’s more of mapping the fields that need to be displayed. This is my configuration. Feel free to design the way you want to.
Now there is an option to choose the REST API’s response as fields in Search filter. I chose title and body_html as fields. This is such a useful feature.
Next is the actions tab, I removed Add button as the intention is not to add a product from this app. It’s only for the Customer support team, hence it’s more of a read-only when it comes to Product information from Shopify’s API. On item click, I gave Open details - Product details
Since we added Product details page earlier, let’s add the source and map the content and we’re all set for the Product flow.
I selected Item details as the Block style and the Source will still be the Shopify REST API as in the Products page, just that content mapping differs.
Although it looks like a number of steps, it is actually quite easy and simple. The most important aspect is the transformer that we write.
Let’s now add two more resources, one for Orders and one for Customers.
In order to fetch information like name, email, phone number that helps identify a Customer, one needs to be on Shopify’s higher plan, the basic plan will not return these. Since I’m on the the Basic paid plan, I did not write a transformer for the Customers resource. Here’s the Shopify API to fetch all Customers associated with a store 👇
https://pasteltshirts.myshopify.com/admin/api/2024-10/customers.json
- Now to Orders. Let’s first add the API and remember that these APIs are GET requests.
https://pasteltshirts.myshopify.com/admin/api/2024-10/orders.json
- I added a transformer function as the Orders API also returns a lot of items.
return response.orders.map(order => {
return {
id: order.id,
order_number: order.order_number,
processed_at: (order.processed_at && new Date(order.processed_at).toLocaleString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})) || "Not Processed",
cost: order.current_subtotal_price,
current_total_tax: order.current_total_tax,
confirmation_number: order.confirmation_number,
// Directly including Customer details
customer_id: order.customer ? order.customer.id : null,
customer_email: order.customer ? order.customer.default_address?.country : null, // Adjust to fetch actual email
customer_created_at: order.customer ? new Date(order.customer.created_at).toLocaleString('en-US') : null,
customer_verified_email: order.customer ? order.customer.verified_email : null,
customer_tags: order.customer ? order.customer.tags : '',
customer_company: order.customer ? order.customer.default_address?.company : null,
customer_province: order.customer ? order.customer.default_address?.province : null,
// Fetching Line Items
line_items: order.line_items.map(item => ({
id: item.id,
title: item.title,
quantity: item.quantity,
price: item.price,
total_discount: item.total_discount,
variant_id: item.variant_id,
vendor: item.vendor,
sku: item.sku, // Add SKU if needed
taxable: item.taxable, // Taxable status
grams: item.grams // Weight in grams
}))
};
});
Here’s the link to Shopify API to cross reference.
Like how we set up a Product page and Product details page, I set up Order and Order details, similar steps. Hence I’m not showing those here.
For Users and Stores, I set the source to my AirTable’s Shopify Base and mapped it to Users and Stores table.
One last thing I did was to add User groups, Admin and Manager. This was more to control scope and visibility.
In order to add a User group, click Users on your app and choose the User groups tab. Here’s how it looks like 👇
Woohoo ✨🙌, I published it and here’s the app link. It’s a fully working app, feel free to sign up and play around. It may not be super useful at the moment but it can be made to.
My thoughts
Although Softr’s REST API is evolving and at the moment is more supplemental to an app from the data it provides, in my opinion, it’s always a mix of REST API and Call API that makes a Softr app powerful.
Infact, one can take forward the “dummy” customer support app that we built now to a fully blown production grade app. All we need is to decide the boundaries of the app, in terms of who sees what, how much is read-only, how to automate a few things, when to invoke REST and when to invoke Call API as far as Shopify information is concerned.
A few practical suggestions:
Ensure you spend enough time on the API that you plan to integrate
Decide on what data you will require from the response
Design your database well enough such that information is not duplicated
Transformers play a very important role in the data that gets filtered, ensure to have default values or display meaningful values instead of null
Have a tab on the rate limit when it comes to API
Conclusion
In this post, we saw how to integrate a Softr app with Shopify APIs and build a starter app to aid Customer support agents corresponding to a store. We added two APIs and multiple pages to make the app decently functional.
We also saw in detail how to make use of AI to write a transformer function.
The idea was to show how to make use of REST APIs as a data source in Softr. If you are a Shopify store owner and want to outsource support as you wouldn’t want to expose all of your data, then building such an app with Softr will be a time saver.
Hope you learnt something new today. Have an idea, a question, feedback or suggestions, my DM is open 😁.
If you plan to sign up for Softr, feel free to use my affiliate link.
Subscribe to my newsletter
Read articles from Sambhavi Dhanabalan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sambhavi Dhanabalan
Sambhavi Dhanabalan
I am an entrepreneur and a full stack developer. I can bring ideas to life. I understand the entire realm of how products work, not just technically but also from a customer success, marketing, sales & partnering viewpoints. Being an entrepreneur has taught me so much, that I could not have learned elsewhere. I am a proud generalist.