Shopify App Proxy. How to I get data from an external database into my store.

fuller
Shopify Partner
25 0 39

What we need is to be able send a single product# or part# to our external site and return on hand inventory levels and price back to the shopify store.  We have an API endpoint in place to return this info.  Not sure how to return this data back into Shopify just yet. What skills/knowledge are needed to be able to call our API endpoint from within a shopify app proxy and return that data back to a Shopify page.   An example of liquid code returned by the App Proxy Server would be nice.

 

I've read Shopify's documentation on App Proxy, but I'm not completely sure I understand the process.

The documentation feels as if it's skipping over certain parts. 

 

For Example, take this section: 

 

AddAnAppProxy.png

 

 

- To add a proxy to your app, make sure the app is set up for the online store area of Shopify

 

I'm confused.  Why are we setting up private App in online store when it says on this page that only public Apps work with App Proxies?  

 

- 1. From your partner dashboard, click apps. To add a proxy to your app.

 

We jumped URLs? from the online store to the partner dashboard between the heading and first paragraph?

 

2.  Click the name of your app.

 

I don't have an app name yet or the app created yet. - click on the Create app button?  

What would I put in as my App URL?  What am I putting in Whitelisted redirection URL(s)?

 

CreateAppFromPartnerDashboard.png

 

3. Click Extensions.

4. In the App proxy section, click Add proxy.

 

App proxy section?,  click on online store..  you will find it there.

 

5. Select a prefix from the Sub path prefix drop-down list. If you want to add a sub path, then enter it in the Sub path field. These settings determine which HTTP requests to Shopify are proxied to the proxy URL entered in the next step. For example, if the sub path prefix is apps, and the sub path is store-pickup, then any path in your shop after https://your-store.myshopify.com/apps/store-pickup is proxied to the provided proxy URL.

6. Enter the URL of your proxy server in the Proxy URL field. This is the URL that will be proxied from the path that you entered in the previous step.

 

- How do I tell shopify that any http(s) requests for single products such as:

   https://progodirect.com/collections/volkel-hex-tap-s-bit-drive/products/tv01-67026, or 

   https://progodirect.com/collections/volkel-tap-wrench/products/tv01-10001 should be sent to the Proxy URL?

 

ProxyURL.png

 

I found another read about Shopify Application Proxy in this Medium thread:

 

 https://medium.com/shop-sheriff/what-is-a-shopify-application-proxy-and-how-can-i-use-it-153bf99d1a9...

 

The pictures helped see the flow.

 

We need a Shopify Application Proxy to be able to call our external API to get price and inventory levels and return

that data to be formatted within a liquid product template.  The way I am picturing the App Proxy working is by intercepting URLs for a single products. i.e. https://progodirect.com/collections/volkel-hex-tap-s-bit-drive/products/tv01-67026 and parsing our the information needed (ie Part#) and calling our API endpoint. 

The data returned by our API endpoint can either be in XML or JSON format.

 

Hoping someone can help us.

 

Best Regards,

Fuller.

 

 

Replies 27 (27)

HunkyBill
Shopify Expert
4845 60 547

Here is how it works. You want to make a secure callback with a product ID to your App. You want to return to the Shopify product page, a correct inventory amount. Your App is private. You installed it in your shop. You set it up to listen to incoming calls (GET) at some endpoint like /a/foo or /tools/goob or whatever. 

 

If you did setup your endpoint correctly, and are listening, you now have a couple things to do. When you get a request, you need to validate it as being from your Shop. Shopify has embedded the HMAC and product ID for your use. If you decide it is legit, you call your inventory service, and ask, hey dude, how much of product ID 123456789 do we have right now? And you get that number, and you send it back to the caller as a JSON response like { variant_id: 12344, quantity: 10 } so that on the front-end shop, you can update the variants. 

 

On the front-end, let us say you use jQuery. So you just do a $.get('/a/foo', { id: 123456789}) and wait for the response. Since you get back JSON, it is easy for you now update your page for customers. 

 

So this is it. Nothing crazy. Sure it seems crazy, but it is pretty easy. The problems are myriad though. Customers can change the Proxy URL in the App Details of the Admin! Sacre-bleu! And the code to compare the HMAC secure signature and payload etc, is very sketchy in explanation, but in the end, it all works. You can use the Shopify App code for examples as they include the verification of HMAC in their code. 

 

SKIP returning Liquid. That is not needed at all, and adds way too much complexity to things. 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
fuller
Shopify Partner
25 0 39

I appreciate the reply.  You make it sound easy enough.

Hope you don't mind answering a few more questions for me and the others that will look to this thread to gather information about using an app to call an external API (not a SHOPIFY API) for retrieving data.

 

The part that I'm think I understand is making the jQuery $.get() call.

I will be making that jQuery call from our theme's section that contains a file called: product-template.liquid 

Sound okay to you?

 

I thought, Only public apps can use app proxies?

Anyway, my question is with configuring the app proxy in the partner dashboard and how this relates to the path inside of my $.get() call.

 

If my app proxy subpath prefix is: apps

and my subpath is: get

then I should be configuring my get call as: $.get('/apps/get/', product.handle);  // note: product.handle is part# for us.

Sound okay to you?

 

I believe Shopify sees this $.get() call, takes whatever the path inside of it is and replaces it with the proxy URL instead?

Am I correct here? that any $get() calls using the app proxy subpath prefix and subpath are replaced with the proxy URL?

 

So the app resides at my proxy URL? Correct?

The proxy URL can be hosted either on the cloud, such as Heroku, or it could be hosted on our own internal server? Correct?

Can Shopify also host/run the app on their own servers?

 

I think, I better stop there before asking further questions.

 

 

 

 

 

masumluf
Excursionist
38 0 9

Hello Fuller, I just created a theme extension and trying to send a http call to my node application, 

here is my http fetch code , 

const appDomain = "https://f38f-103-117-***-9.ngrok.io/auth?shop=spr-test-store.myshopify.com/";
  fetch(`${appDomain}/test/api`, {
    method: "GET",
    headers: {
      mode: "no-cors",
    },
  });

and here is my node application api implementation

  router.get("/test/api", (ctx) => {
    ctx.response;
  });

I am getting CROS error. and my proxy is 

sub_path_prefix = apps,
sub_path = get,
proxy_url = https://f38f-103-117-***-9.ngrok.io/auth?shop=spr-test-store.myshopify.com

if I send request using given format below I see 404 error,

 fetch(`apps/get`, {
    method: "GET",
    headers: {
      mode: "no-cors",
    },
  });

so what Should I do now to access /test/api from my local node application ?

HunkyBill
Shopify Expert
4845 60 547

It is not clear what you setupin Shopify. But if indeed you chose app and then get for your Proxy, then you are correct in doing a fetch('/app/get') on your front-end callback. Thing is, if you are getting 404, then a couple of things. You may have screwed up a set up with the Proxy and maybe it is set to /app/get-1 or something. It happens. You can check in the store settings of the App itself in the App listing under about. This has been a frustration with App Proxy since forever, in that the merchant can monkey with the URL, and break it, and or, in set up, you make a mistake and then secretly pay the price.

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
fuller
Shopify Partner
25 0 39

Seems my previous post did not go through.. I will try it again.

 

HunkyBill, thank you for your reply.  Hope you don't mind if I ask a few more questions to confirm I am understanding the concepts, and as a reference for the others that find this thread in the future.

 

Only public apps can use app proxies.  It would appear that I need an app proxy to call our inhouse API to get external data, right?

Would I still have to configure the private App settings in my store if I intend to use an App Proxy?  

 

In my Shopify Theme->Section->product-template.liquid, I want to add some jQuery script to call my App.

For example: $.get('/apps/get/', product.handle) { // call appProxy,  Note: we use product.handle as our Part# } 

/apps -  See $.get(), this is my AppProxy subpath prefix 

/get - See $.get(), this is my AppProxy subpath

 

When the script is executed it will make a call to the proxy URL. 

In otherwords, /apps/get is replaced by my proxy URL, and the $get() call is made to my APP hosted at this API endpoint.

 

Does this sound correct?

 

My App in turn will make another API call our external server to retrieve partInfo: price and stock quantity.

My App will receive a XMP or JSON file, convert it, and return the information as part of the $.get callback

 

Can I use PHP to write the App?  Not familiar with Rails, Node, or Python.

Can the App be hosted by Shopify, or does it have to be an external server or a cloud base platform such as Heroku?

 

Looking forward to your reply?

 

HunkyBill
Shopify Expert
4845 60 547

@fuller wrote:

Seems my previous post did not go through.. I will try it again.

 

HunkyBill, thank you for your reply.  Hope you don't mind if I ask a few more questions to confirm I am understanding the concepts, and as a reference for the others that find this thread in the future.

 

Only public apps can use app proxies.  It would appear that I need an app proxy to call our inhouse API to get external data, right?

Would I still have to configure the private App settings in my store if I intend to use an App Proxy?  

 

All that means is that an App you setup in your partner dashboard, that you installed in your shop, and that has an oAuth token for access to the resources you need. It does not mean an app in App store, or anything like that. It just means you are running an App in the cloud somewhere, reachable by Shopify. Hence Public.

 

 

 

In my Shopify Theme->Section->product-template.liquid, I want to add some jQuery script to call my App.

For example: $.get('/apps/get/', product.handle) { // call appProxy,  Note: we use product.handle as our Part# } 

/apps -  See $.get(), this is my AppProxy subpath prefix 

/get - See $.get(), this is my AppProxy subpath

 

When the script is executed it will make a call to the proxy URL. 

In otherwords, /apps/get is replaced by my proxy URL, and the $get() call is made to my APP hosted at this API endpoint.

 

Does this sound correct?

 

 

Yes, it does. Perfect... you call your endpoint with just the setup you used in the App partner dashboard for the proxy. Shopify then takes care of formatting the request with security based on your API secret. Neat eh...

 

My App in turn will make another API call our external server to retrieve partInfo: price and stock quantity.

My App will receive a XMP or JSON file, convert it, and return the information as part of the $.get callback

 

You are on a roll now!

 

Can I use PHP to write the App?  Not familiar with Rails, Node, or Python.

 

You can. You can use anything to write an App as long as it does Internet computing. No problem. 

 

Can the App be hosted by Shopify, or does it have to be an external server or a cloud base platform such as Heroku?

 

I use Heroku, but you're free to use any server setup you want, so long as your server is reachable by Shopify as https://something.something.com for example. 

 

 

Looking forward to your reply?

 

You're in doubt! Hah... lucky you.

 


 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
tetranz
Tourist
10 0 8

Does the proxy really add any security?

 

I understand about the signed request from Shopify to the app but anyone can still access the URL https://store-name.myshopify.com/a/foo at the store.  That URL is still open to the world isn't it? What does the use of the proxy really achieve?

 

The signed server to server request prevents someone proxying the response from their store or other site but as far as I can see, it doesn't do anything to make the Ajax request "secure".

HunkyBill
Shopify Expert
4845 60 547

Yes, anyone can hit that end point, but it is SHOPIFY, not your App. Shopify formats the request that goes to your App, and then your App decides if it is legit or not to deal with the call, and return data.

 

So yes, this is secure. You ask what does this achieve? It allows for Ajax calls without CORS issues. It means you can return HTML/Liquid or JSON data to a front-end from a back-end... it means a lot. Do you not see that? Proxies are nice.

 

Soon enough this will be replaced with sections from Apps, but until then, this is the way to go.

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
tetranz
Tourist
10 0 8

I was reading your post where you said:

 

You want to make a secure callback with a product ID to your App.

What did you mean by "secure"?

 

Sure, the proxy avoids your app needing to provide CORS and nobody else is able to request from your app directly, they need to go through Shopify but as far as I see, it doesn't do anything for security if that Ajax request returns some sensitive information.

HunkyBill
Shopify Expert
4845 60 547

Nothing can help you here. If you are scared of returning sensitive information in a callback, that is your problem, and no technology can help you.

 

What is your actual problem? Are you just speculating that you think you can't do something here?

 

There is very little challenging to learn about the Proxy. If you're scared of the boogie man intercepting your XHR response and causing you grief, then you can certainly add your own layer on top of HTTPS and the proxy pattern. Feel free. Encrypt your payload next level, but don't screw that up or you're screwed 🙂

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
dreadmill
Shopify Partner
7 0 1

I know this has been a while but I feel this is an important point. Many people think "Just use an App Proxy and you are safe!" and unfortunately Shopify also communicates it like that a little bit. 
Unfortunately, this is far from the truth. While an app proxy can shield your App URL, still anyone can extract your App Proxy URL and bruteforce that one without problems.
So make sure that if the customer is not logged in, NEVER expose sensitive information through an App Proxy, because anyone can exploit it.
For example if you create an endpoint that takes a customer id and returns email, name and birthdate. Then you add an App Proxy for that endpoint. That adds zero security because anyone can just go to the network tab in the browser, copy the App Proxy URL and send millions of requests that way. 

In case the customer is logged in, you can either check for a customer_id added by the proxy or you can also use your app secure key to create an hmac in liquid at page load time with the logged in email (which is inaccessible for the browser) and check in your app code if that matches once you receive any request.

evaldas_92
Shopify Partner
40 0 17

I'm a little concerned about latency introduced by app proxy. I've tested response time to my app directly and it reports between 150-250 ms. However, when the request goes through an app proxy, it ranges between 600-700 ms - that's more than double. Response's content/type is application/json, so there's no liquid rendering involved. 

 

Is there anything I can do to reduce latency? I've noticed many apps send requests directly to their APIs rather than going through the app proxy, I can imagine this is why?


Best regards,

Evaldas

HunkyBill
Shopify Expert
4845 60 547

When you say "many Apps send requests directly to their API" that may be true for mickey mouse who cares API calls, but it does not work well for secure calls. I would say at best, these calls use a token to decide whether to respond or not.

 

App Proxy is for front-end code to call your App with some security. There is really no other way to do it unless you want to risk having your App hacked. And if that happens, and it affects your merchant, be prepared to lose your privileges from Shopify to even operate Apps.

 

And how are you measuring latency, and how are you sure it not simply your network that is slow. For example, of your measured 700ms slow response, how much of that is Shopify, how much is pure Internet, and then how much is hitting your server. If you broke that out, it would be revealing.

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
devmon
New Member
10 0 0

@HunkyBill I stumbled upon this when I am trying to figure out how to create a simple Product Page based app that all it does is decorate/work with a Product Image on the Product info. It sounds like App Proxy is the one to actually embed App on Product Page.

But in my case, since I don't have a third-party inventory API to call at all, I don't really need to call $.get('/a/foo', { id: 123456789}) to get product info, right? If I have a remote endpoint that displays image given a param, I could just do $.get('/a/tool', { image_url: "URL"}) and embed the external html in an iframe, right?

 

Shopify docs are a little confusing on App integrations on Product pages, it sounds like the Merchant needs to make manual liquid template updates post app-install. I am not sure if that's true.

HunkyBill
Shopify Expert
4845 60 547

You are indeed free as a bird to call any URL you want from your Shop theme code. So on a product page, if you have some URL where special images are, go right ahead and make that call. Note that that URL is public, and allows GET requests from any domain, so no CORS problems. If you have that, you do not need an App Proxy. An App Proxy is only when you have to protect credentials, tokens, and resources from public use! Obviously you cannot call an API with login credentials or an API needed a secure token with a public call. Those are private resources, hence the App Proxy exists to protect you.

 

So go crazy! Just call your naked endpoint and do what you need to do! If there is no security involved then who cares!

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
devmon
New Member
10 0 0

@HunkyBill Yeah, I see modifying the Theme code will allow anything to work, the blocker is whether I can do that as part of App Install + App configuration without Merchant having to edit their theme code. I see some apps able to configure how Merchant want to place the module on the Product page etc, but I don't know if there's a special API for that purpose. 

qaiser55
Tourist
13 0 0

Hi Bill, 

I have a confusion regarding this process. I have a third-party app (A custom app) that I want to use for product customization. I have been able to get data from my app using proxy app but I don't only need data, I also have some pages there that the customer needs to visit, visually customize the product and then return some data. Is this something that can be done using Shopify?

Thanks

HunkyBill
Shopify Expert
4845 60 547

Of course. You have an endpoint. It can be called from ANY place in the theme. So when you need to send data back to you App, place a callback to the endpoint with the data. Obviously you'll be overloading your App endpoint receiving the callbacks to recognize what the incoming request is, and deal with the building of the correct response.

 

So there is zero reason you cannot place /app/tool/ calls or whatever you chose all over, and POST in {data: details} as needed, or {foo: "beers"} ... totally up to you. 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
qaiser55
Tourist
13 0 0

Thank you Bill for your reply.

But I think you misunderstood my question. I was able to use proxy app to send data to my app using ($.get or $.Post) and was able to receive the response as well. The trouble I am having is that I actually need to take the customer from Shopify Page to my Custom app and then Post data from my app back to the Shopify Product page. This is what I am unable to achieve. If I redirect customer to my app using simple URL redirect with product id and data, then I can't see a way to receive a response from my app back in the shopify store.

Thanks a ton again for all your help.

HunkyBill
Shopify Expert
4845 60 547

I did not misunderstand your question. Your product customizer cannot be a separate App if you expect it to work in Shopify product situations unless you communicate with it via the Proxy pattern. You can now understand why product customizers are non-trivial, and why over the years developers like me have stopped trying to service them except in the trivial cases. It is not an easy pattern to master.

 

You'll eventually figure it out. Move the part of your customizer that you currently have in your App to Shopify product theme liquid, use the Proxy to handle all the custom calculations and data manipulations that only your App can provide, and boom, Bob is your uncle. Expecting to place your customizer App inside a Shopify theme is the toughest row to hoe, to maybe give yourself a higher chance of success by not trying that as a first go around.

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
qaiser55
Tourist
13 0 0

Hi Bill,

Thanks for your reply again. Really appreciate it. So just to make sure, what you are saying is that I cannot run the Customizer app separate from shopify, so that means there is no way for me to embed the app inside shopify page (Like in an Iframe). The easier way would be to make a customizer by writing code for customizer directly inside Shopify Theme Code and then get required data from my endpoint (App's API) using App proxy (via some GET request) and then do whatever I need within Shopify Theme.

But what I fail to understand in this case is for some people it would be easier to code in other languages rather than writing code inside Liquid theme, which gets very messy sometimes. So why won't shopify allow you to embed your app on StoreFront like it does in the admin section? Is this because of security reasons?

Thanks

HunkyBill
Shopify Expert
4845 60 547

You can iframe anything you want. Go for it. You will likely encounter the same headaches Shopify has with embedded Apps as they are also rendered as an iframe.

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
qaiser55
Tourist
13 0 0
Hi Bill,
Thank you for your reply.

Following up on your idea to build customizer inside shopify, I have a couple of questions.

1. Say that I build a customizer inside shopify and have some custom data about a product which I get from html fields that the user customized. How do I use that data to tie it with a confirmed order so that the merchant can see what kind of customized item the customer wants.

2. When the user customizes app, he is not necessarily signed in. He is signed in after he presses checkout button on the cart page. How do I tie it to the user.

3. Once the user confirms the order, I want to send the confirmed order details that is the products in the cart along with customized data and customer id to my external database. I can use proxy app to send data for example, but how can I execute that Post request to my external endpoint when the user confirms the order?

Thanks alot.
HunkyBill
Shopify Expert
4845 60 547

1. Use line item properties. That is what they are for!

2. every customer is assigned a cart token that you'll eventually be able to use with the order. Prior to checkout, you use that.

3. subscribe your App to the orders/paid or orders/create webhook. Then you get the order, and you can tidy everything up with your App, the cart token match and whatever else you need to do

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
jankadlec
Shopify Partner
14 0 1

Hi @HunkyBill 

 

thanks for explanation - I have the same experiences with App proxy delays - our service responds typically in 50ms, after proxied it takes 600 - 800ms.

 

We hit this problem: https://support.google.com/google-ads/thread/37647995?hl=en

 

My first idea is that Google tights "same origin" rule for all assets and sriptTags are breaking it. My idea was to proxy scripttags using app proxy - but there is the latency again ;-( 

 

Is there some option to use appProxy without HMAC and shop domain (however I understand it's security pros), but for downloading JS file from CDN it does not make much sense to sign the requests and spend precious time, right?

 

Thank you for any suggestion

 

Jan

 

 

HunkyBill
Shopify Expert
4845 60 547

I would not use Script tags. They have a totally different use case than App Proxy, and as you are seeing, they cause problems due to Google policies, something neither you or Shopify can control. Why would use a Script Tag anyway? App Proxy should be good enough. Are you sure you understand the architecture here?

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
jankadlec
Shopify Partner
14 0 1

@HunkyBill 

we use ScriptTags to inject JS assets to the Shopify pages - we are creating app, and we do not have access to the themes. We need to inject some dynamic content to the pages and for this we need to use AJAX to get some dynamic data - the JS widget on page requests data trough app proxy from our backends - we use appProxy in order to our backend get the right shop domain and security hash.

 

We solved that by copying the JS asset of the widget to Shopify CDN and use it's URL in script tag