Code is an amazing man-made wonder, and we, at Shipsy, are in absolute awe of it!
So, to all our coding fellows - “In Code, we Trust!”
We want to share with you some of the work that we are doing; essentially, how we catered to our multiple Shopify app clients via a single server.
Before we get into the granular details, it is important to understand the driving force behind this.
There are three crucial components of Shopify SDK:
- Shopify App Bridge
- Shopify Auth
- Shopify API
The Shopify App Bridge connects the client-side with the Shopify server. The Shopify Auth and Shopify API libraries perform the underlying and facilitating tasks, such as communications, authentication, and validation.
Now, both these libraries are stateful, this means that once they have a “state” variable, context object in this case (we will revisit this in later sections), these libraries don’t allow any change in it.
So, once the context object has a client ID, Shopify libraries will not allow you to change it, and thereby, the Shopify libraries only support “one-server-one-app” architecture.
However, we wanted to change that!
Achieving a “create once, use infinitely” capability on our Shopify app to ensure that our entire customer base from different domains is able to use the same product.
Essentially, we wanted to make the Shopify libraries “stateless” and allow us to dynamically change the context object as per the incoming connection requests.
Now, this was something like getting your own highway for your specific traveling needs!
Yes, it was nothing short of a Utopia, but Hey! We at Shipsy realized our Utopia!
Presented here, is a walk-through of our entire endeavor and a little glimpse of what it took to get our own highway!
Challenges to Our Approach
Shopify’s API libraries are stateful, which means that all the APIs share a global context object. If you don’t have core libraries, you cannot use this context object as per your wishes.
Before we move ahead, let us have a brief discussion about this context object.
The context object has all the information of the Shopify API key and API Secrets for each app. Both of them play an essential role in authentication and verification via session tokens and JW tokens.
So, the Shopify app libraries have only one context object and in that context object, there is only one combination of API Key and API Secret.
As this context object is being used everywhere - for sending app requests to the Shopify server and getting responses back from the same - we were not able to use the single server for serving app requests from multiple apps.
So, what we did can also help the developer community across the globe. The developers can learn from this approach and leverage the Shopify server to serve multiple apps from a single server.
Overcoming Context Object Challenges With Custom Libraries
We custom-coded the Shopify API and Shopify Auth libraries.
While the Shopify Auth library for our apps is entirely built from scratch, line-by-line, Shopify API is coded as per the business’ unique needs.
By doing this, we converted Shopify libraries from stateful to stateless libraries!
Hence, whenever a request comes from the Shopify dashboard, or from the Shopify App Client to the server, instead of using Shopify libraries, we use our custom-coded Shopify Auth library.
Next comes a step that is one of the many fantastic things code can help us developers do!
We have a custom logic that identifies which app is requesting this service.
Once we know which app is requesting the connection, we can pass the context object in every function with request-based parameters, and it is no longer global.
Next, a pure function (which is also custom coded), takes the data from this context object parameters and sends it to the Shopify server.
While a major hurdle was overcome, there was still one consequential challenge left.
How to Know Which App to Serve?
Whenever we create an app, we set a custom subdomain on the basis of its domain and we tell the app the correct server API so that it hits the right server.
The config file stores the client details, on the basis of which, we figure out which app needs to be served.
Now, we configured our DNS such that all the requests coming on this domain are sent to the Shipsy server.
All the incoming app requests are encountered by the frontend and we identify which app needs server access. Once this is done, all the other communications are then internally handled by custom Shopify Auth and Shopify API.
This Shopify API is handling all the conversations we are having with Shopify, such as any data we require from Shopify, etc. Our custom Shopify Auth handles all the logic on the server-side of the Shopify App.
Now we will talk about the client-side architecture of our Shopify App.
Overcoming the Client-Side Challenges in Custom Library Riddle
For all the pages in the front end, we call the APIs indirectly, as our app is loaded in Shopify, and now we are making API calls, such as soft data, label generation, virtual series generation, etc. there only.
This is because earlier the request authentication and verification were managed by Shipsy.
However, in Shopify's case, authentication is done at Shopify’s frontend and our app backend and frontend.
We know that you might need to read that sentence again.
So, here is a little something to keep you motivated to do so:
Let us try to understand this with the help of an example.
How We Authenticate Our Frontend With Our Backend?
Suppose we load a page or data on a page.
Now, before that request is processed, sync is loaded/ordered, and the frontend sends the request to Shopify.
In our backend, our middleware processes the session token, which has many values and details, such as - expiry time, Shop Name, etc. which is a unique identifier in our case.
As soon as the app frontend is loaded, initially, a skeleton is loaded. This skeleton loads the Shopify App Bridge client on the browser of the app user.
Now, every time the user sends a request, we include a session token in its headers, which we get from the Shopify App Bridge. This session token is verified on our Shopify app backend (server) to confirm whether the request is coming from a genuine source or not.
Once we know that the Shopify request is true and valid, the request gets processed normally.
Next, we discuss how this process generated desirable results for the entire Shipsy ecosystem.
Results of Custom Coding the Shopify Libraries
No Automatic Logouts
Earlier, when we used to manage authentication and verification at our end, we used session cookies for the process.
Now, once these session cookies expired, the clients were automatically logged out and that led to redundancy in the user experience.
Now, the authentication and verification are handled by our custom Shopify Auth library and the logouts don’t happen automatically.
Single Server for Multiple Clients
By creating custom libraries for our Shopify app, we are now serving multiple clients via a single server, which obviously comes with a lot of operational and management advantages.
Multilingual Shopify Stores
Being able to regulate the context object, we are now enabling organizations to use the same admin account for managing multiple stores that use multiple languages.
Every new undertaking in coding comes with a slew of learnings and this one also brought many of them to our team. We plan to leverage them across multiple scenarios and encourage our fellow developers to follow the suite.
Experiential learning impacts in the Dev community can spur a huge wave of transformation that benefits masses at a large scale.
And, at Shipsy, we believe in driving such changes and welcome the change drivers with an open embrace and an excellent Dev culture.
Wish to experience the wave of change? Get onboard with Shipsy and get started with your journey with our Dev Team.