We're moving the community! Starting July 7, the current community will be read-only for approx. 2 weeks. You can browse content, but posting will be temporarily unavailable. Learn more

How do I make a call to the storefront API from my emeded Apps public API end points

How do I make a call to the storefront API from my emeded Apps public API end points

Giltee
Shopify Partner
17 3 6

I am trying to do something I thought would be simple but I can't seem to figure out how to get the proper session on my public endpoints to make the call. I started off using the GraphQL explorer which got my the mutation I wanted:

 

 

mutation checkoutCreate($input: CheckoutCreateInput!) {
  checkoutCreate(input: $input) {
    checkout {
      webUrl
    }
    checkoutUserErrors {
      code
      field
      message
    }
    queueToken
  }
}

// variables
{
"input": {
"allowPartialAddresses": true,
"buyerIdentity": {
"countryCode": "US"
},
"customAttributes": [
{
"key": "",
"value": ""
}
],
"lineItems": [
{
"customAttributes": [
{
"key": "",
"value": ""
}
],
"quantity": 1,
"variantId": "gid://shopify/ProductVariant/45806359249211"
}
],
"note": "",
"shippingAddress": {
"address1": "",
"address2": "",
"city": "Test",
"company": "",
"country": "US",
"firstName": "",
"lastName": "",
"phone": "",
"province": "CA",
"zip": ""
}
},
"queueToken": ""
}

// response
{
"data": {
"checkoutCreate": {
"checkout": {
"webUrl": "https://quickstart-0f3b6685.myshopify.com/79491432763/checkouts/848734768d5e803df1346cc29fd708c3?key=28fafff6a1b88ce729969b9935d42cb6"
},
"checkoutUserErrors": [],
"queueToken": null
}
}
}

 

 

Cool this is exactly what I want. Now from what I have read that I would be able to query the Storefront API from my public end points. But when I try to do so I am getting errors when creating the session. In my authenticated backed API, where i fetch data for my embedded App I can get the session from the response variable like so: 

 

app.get("/api/shop-data", async (req, res) => {

    const client = new shopify.api.clients.Graphql({
      session: res.locals.shopify.session, // doesnt work on the public end points
    });

    /* Fetch shop data, including all available discounts to list in the QR code form */
    const shopData = await client.query({
      data: {
        query: SHOP_DATA_QUERY,
        variables: {
          first: 25,
        },
      },
    });

    res.send(shopData.body.data);
  });

I am guessing this is because the call is coming from the storefront and not the backend. I went through the documentation and tried using the shopify api library:

 

 

 

 

	app.get("/bundle/checkout", async (req, res) => {

		try {

			 const shopifyAPI = shopifyApi({
				// The next 4 values are typically read from environment variables for added security
				apiKey: 'xxxx',
				apiSecretKey: 'xxxxxxx',
				scopes: ['unauthenticated_read_checkouts,unauthenticated_write_checkouts'],
				hostName: 'localhost',
			 });

			 const adminApiClient = new shopifyAPI.clients.Rest({...shopifyAPI.session});

 

 

 

 

I am getting the following error: 

 

 

 

TypeError: Cannot read properties of undefined (reading 'shop')
2023-07-23 17:01:50 │ web-backend  │     at new RestClient (/Users/mpmadmin/shopify/build-a-bundle/node_modules/@shopify/shopify-api/lib/clients/rest/rest_client.js:12:40)
2023-07-23 17:01:50 │ web-backend  │     at new RestClient (/Users/mpmadmin/shopify/build-a-bundle/node_modules/@shopify/shopify-api/lib/clients/rest/rest_client.js:104:5)
2023-07-23 17:01:50 │ web-backend  │     at file:///Users/mpmadmin/shopify/build-a-bundle/web/middleware/qr-code-public.js:81:28
2023-07-23 17:01:50 │ web-backend  │     at Layer.handle [as handle_request] (/Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/layer.js:95:5)
2023-07-23 17:01:50 │ web-backend  │     at next (/Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/route.js:144:13)
2023-07-23 17:01:50 │ web-backend  │     at Route.dispatch (/Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/route.js:114:3)
2023-07-23 17:01:50 │ web-backend  │     at Layer.handle [as handle_request] (/Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/layer.js:95:5)
2023-07-23 17:01:50 │ web-backend  │     at /Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/index.js:284:15
2023-07-23 17:01:50 │ web-backend  │     at Function.process_params (/Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/index.js:346:12)
2023-07-23 17:01:50 │ web-backend  │     at next (/Users/mpmadmin/shopify/build-a-bundle/node_modules/express/lib/router/index.js:280:10)

 

 

 

 

Can someone please help me out? How can I get the session to make a request from my public node end points to the store front API to create the checkout link and then redirect the user to it?

Replies 3 (3)

Trudy
Shopify Partner
11 1 4

So you're trying to make a fetch call from the frontend?  I wrote a blog post on how to do this, http://www.toomanytabs.xyz/blog_posts/the-easy-way-to-do-the-shopify-storefront-api-graphql-with-fet... The top part is a little outdate, but the JS is the same once you get the storefront API key.  

 

Also when you're using the Graphical app to form your query, make sure you're on the storefront api and not the admin api, because the queries might be slightly different

Looking to customize your theme? Don't hire a developer - instead check out Design Packs! https://apps.shopify.com/design-packs
Giltee
Shopify Partner
17 3 6

Hey thanks for the response. I actually want to do it from the public NodeJS end points I created. I am on the storefront API and I have successfully returned the URL I need here. The issue is getting the session to setup the client. On the admin protected routes I am able to create the client with out issue:

 

const adminApiClient = new shopify.api.clients.Rest({session: res.locals.shopify.session});

    const storefrontTokenResponse = await adminApiClient.post({
      path: 'storefront_access_tokens',
      type: DataType.JSON,
      data: {
        storefront_access_token: {
          title: 'This is my test access token',
        },
      },
    });

    const shop = adminApiClient.session.shop;
    const storefrontAccessToken = storefrontTokenResponse.body['storefront_access_token']['access_token'];

    const storefrontClient = new shopify.api.clients.Storefront({
      domain: shop,
      storefrontAccessToken,
    });

 

On my public routes I am not able to access the res.locals.shopify.session variable but I need a session to create my client and retrieve the access token. How do I get the session for the public end points?

MadsN
Shopify Partner
9 0 4

Looking at the source for clients.Storefront it seems like the doc is wrong and that the setup should be like this.
https://github.com/Shopify/shopify-api-js/blob/9dd9284376deaca14598e8dc96c90b868e03086b/packages/sho...

const storefrontClient = new shopify.api.clients.Storefront({ session: session, storefrontAccessToken, });