MONEI / Shopify-api-node

Node Shopify connector sponsored by MONEI
https://monei.com/shopify-payment-gateway/
MIT License
946 stars 278 forks source link

Browser support #120

Closed lrettig closed 7 years ago

lrettig commented 7 years ago

Hello,

I understand that this module was not designed to work in the browser (cf. #88), but it almost does, and I see a lot of value in being able to run this in the browser. I'm building a serverless SPA web app and I'd really, really like to be able to work with the Shopify API from within the browser.

I was able to overcome the issues in #88 by adding the following to my webpack config (based on https://github.com/MONEI/Shopify-api-node/issues/88#issuecomment-198683227):

  {
    test: /shopify-api-node.*\.js$/,
    loader: 'transform?brfs'
  },

Unfortunately I had to apply this only to the files in this module because it created errors in other modules (such as aws-sdk). I'm still getting the following warning from webpack:

./~/shopify-api-node/index.js
Critical dependencies:
131:23-53 the request of a dependency is an expression
 @ ./~/shopify-api-node/index.js 131:23-53

(cf. https://github.com/webpack/webpack/issues/196 for more commentary on this lazy loading issue)

But it does appear to be working. However, I'm now running into a more fundamental issue. This module uses fetch which, inside the browser, attempts to fire off an OPTIONS call to the shopify API, which is resulting in a 404:

OPTIONS https://SHOPNAME.myshopify.com/admin/shop.json 404 (Not Found)
localhost/:1 Fetch API cannot load https://SHOPNAME.myshopify.com/admin/shop.json. Response for preflight has invalid HTTP status code 404

Basically, this appears to be a CORS issue, as discussed in

It seems that one workaround is to use Application proxies but that seems to defeat the purpose of writing a front page app. Any ideas how to work around this issue?

lpinca commented 7 years ago

I fear there is no way around that. There is no support for JSONP and all requests should be performed server-to-server.

It is not a good idea anyway as it makes the credentials/token publicly available.

alexandresaiz commented 7 years ago

@lrettig I don't really see why would you use this 'in the browser'. This module was born to live in a server and unless this world gets burnt by the sun 🌞 , it will live in thousands of servers worldwide.

lrettig commented 7 years ago

@alexandresaiz From my perspective it's about indirection and user experience. Requiring all Shopify API requests from a frontend, single-page web application to hit the backend, then hop from there to Shopify and back again, adds an additional layer of indirection, slowing things down and reducing the UX. My app is built using AWS Cognito which generally obviates the need for a backend since credentials can be securely generated and stored in the frontend. Maybe it's too much to ask for (and I agree that it's a bit beyond the scope of this project), but it would be nice to be able to access other services in a similar fashion.

alexandresaiz commented 7 years ago

@lrettig It depends what your app does. I'm one of the MoonMail members: a fully SPA totally Serverless. There, yes it makes sense this approach. In Shopify, you might end up reaching API limits or struggling to paginate with your approach. In any case it's interesting to give it a try. Would you mind sharing your code of the skeleton?

lrettig commented 7 years ago

@alexandresaiz which code are you referring to? Right now I'm using a small piece of ruby on the backend (based on the wonderful https://github.com/kevinhughes27/shopify-sinatra-app) to establish the shopify session, and using AWS Cognito federated developer-authenticated credentials to get an AWS access token, then passing this to the frontend (written in ReactJS). Up to now, all additional communication with my database happens directly from the frontend using the Cognito credentials, although as discussed here it looks like I'll have no choice but to hit the backend to touch Shopify data.

buggy commented 7 years ago

FWIW - I've got publicly available skeletons for an embedded Shopify app using React (https://github.com/buggy/shopify-react-starter) with a Serverless backend (https://github.com/buggy/shopify-serverless-starter). For the apps I've been building (or looking at building) it always made sense to call the Shopify API from my own Lambda's rather than directly from the browser.

PS: Both projects are work in progress but should be complete in the next few days.

alexandresaiz commented 7 years ago

@lrettig now you have the @buggy interesting shot!

@buggy I've just sent a dm to you via email.

lrettig commented 7 years ago

@buggy @alexandresaiz thanks, wish I had seen these a few weeks ago 👍