Categories
Tech

Setup environment to develop Shopify application using PHP and React

1. Shopify architecture

1.1. Shopify

Shopify is a commerce platform that allows anyone to set up a store and sell products.

Site owner (merchant) doesn’t need to own neither hosting nor domain. Shopify provides all.

Developers can build:

  • Themes to customize store’s appearance.
  • Applications (plugins) to customize store’s behaviours.

1.2. Shopify public application

This type of application is written by the third-party developer. Can be installed on any store. After install, the application holds an access_token of that store, which is needed to make API request to store’s resources (products, orders, customers…).

Each public application defines 2 public URLs.

  1. Allowed redirection URL(s): Used for Oauth authentication during installation.
  2. App URL: Main URL of the application.

In store’s admin interface, Shopify loads application inside iframe, using its App URL.

Because of this design, app developer must prepare a server to serve his application, unlike other e-commerce systems (WordPress, PrestaShop, …). This way, developer protects app’s code and database; easier debugging, updating and distribution.

Developer can use any language to build the app. In this article, we choose React as frontend and PHP as backend, because:

  • We used PHP for years (despite NodeJs works nicer with React).
  • Shopify has its own set of React components: Polaris.
    • Polaris provides consistent experience while using the application, like other built-in parts of Shopify, makes the app looks officially.
    • Use create-react-app to run an independent React application. This is the easiest way to create a React app.

2. The goals

So far, we have 2 independent applications: Backend (PHP with any framework) and Frontend (React by `create-react-app`).

We’ll implement Shopify public application with below flow:

  1. App URL calls to PHP backend, here we handle Shopify request: detect store, validate installation status, access Shopify AdminRest APIs…
  2. Backend redirects to React, bring all necessary info. React will be displayed in Shopify admin interface.
  3. React communicates with backend through API.

3. Problems with our design

1. Does it save to redirect Shopify requests from PHP to React?

2. PHP and React are 2 separate applications, but they must run on the same domain for some features to work correctly (toast…). How to serve backend + frontend in only 1 domain?

This is toasts

3. How to expose that domain to internet, under SSL (Shopify requires)?

4. Solve problems

4.1. Redirect from backend to frontend

Normal request from Shopify to app is nothing special. It only contains 5 query parameters:

"hmac": "ae043f1b58949762c78ab968223bd51b54f50d48887d13609c0a8ac99ec4f1e2",
"locale": "en-US",
"session": "467bba8be490992dcfe0ed99a44361fd0ec801eb8a0c7ecc9ccb8b9191b024f0",
"shop": "store-name.myshopify.com",
"timestamp": "1598501933"

Easy to redirect. After do validation on backend, we can safely make a redirect to frontend, carries all those parameters.

This is solved!

4.2. Serve backend & frontend on same domain

By using webserver proxy, we can route all requests from a domain to another domain internally.

Assume we have backend app at http://backend.local, frontend app at http://frontend.local, final domain to serve both backend & frontend at http://app.local.

app.local/backend    --->    backend.local
app.local            --->    frontend.local

Complete example:

  • Apache2
<VirtualHost *:80>
    ServerName app.local
    ServerAlias www.app.local
                                                                                                                                           
    ProxyPass /backend/ http://backend.local/
    ProxyPassReverse /backend/ http://backend.local/
                                                                                                                    
    ProxyPass / http://frontend.local/
    ProxyPassReverse / http://frontend.local/
</VirtualHost>
  • Nginx:
server {
    listen 80;
    index index.php index.html index.htm;
    server_name app.local;

    location /backend {
            proxy_pass http://backend.local;
    }
    location / {
            proxy_pass http://frontend.local;
    }
}

This is solved!

4.3. Expose SSL domain

Ngrok is a simple but powerful solution. Just make a simple configuration file ngrok.yml:

tunnels:
  first-app:
    proto: http
    addr: app.local             # forwarding target
    host_header: rewrite        # rewrite HOST (header line) to forwarding address
    subdomain: my-app           # create real domain at http(s)://my-app.ngrok.io
    inspect: true               # enable inspecting all incoming requests
                                  to http(s)://my-app.ngrok.io
                                  at web interface http://localhost:4040
  second-app:
    ...
    ...

Then run all the tunnels: ngrok start --all, you’ll get this similar result:

Ngrok exposes our localhost app.local into 2 domains: SSL and non-SSL. Of course, we will use the SSL one due to Shopify’s requirement.

Here is the final URLs mapping:

https://my-app.ngrok.io/backend   --->   http://app.local/backend   --->   http://backend.local
https://my-app.ngrok.io/          --->   http://app.local           --->   http://frontend.local

This is solved as well!

Use https://my-app.ngrok.io/backend... for your app’s App URL.

Recap

That’s all for the first step of setting up environment.

Further development is straightforward. Polaris is just a set of predefined React components and quite comfortable to work with.

Happy coding!