In February, we released the second version of Marketplace Kit: a collection of boilerplate app code and documentation allowing third-party developers to integrate with Shopify, build selected commerce features and launch a world-class marketplace in any channel.
Previously, we used the node app generated by the Shopify command-line interface (CLI) as a foundation. However, this approach came with two drawbacks: If changes are made to the Shopify CLI, it would affect our code and documentation. Also, we had limited control over best practices, which forced us to use the CLI’s node app dependencies.
Since then, we’ve decoupled code from the Shopify CLI and separated the Marketplace Kit sample app into two separate apps: a full-stack admin app and a buyer-facing client app. For these, we chose dependencies that were widely used, such as Express and NextJS, to appeal to the largest number of partners possible. Open-sourced versions of the apps are publicly available for anyone to try out.
Shopify’s APIs mentioned or shown in this article:
Here are a few ways we leveraged Shopify’s APIs to create the merchant-facing Marketplace admin app for version 2.0.
Before We Get Started
JWT Authentication with App Bridge
Let’s start with how we chose to handle authentication in our apps to assess a working example of using an internal library to ease development within Shopify. App Bridge is a standalone library offering React component wrappers for some app actions. It provides an out-of-the box solution for embedding your app inside of the Shopify admin, Shopify POS, and Shopify Mobile. Since we’re using React for our embedded channel admin app, we leveraged additional App Bridge imports to handle authentication. Here is a client-side example from the channels admin app:
app object, which is an instance of
useAppBridge, is used to pass contextual information about the embedded app. We chose to wrap the
authenticatedFetch function usage inside of a function with custom auth redirecting. Notice that the authenticatedFetch import does many things under the hood. Notably, it adds two HTTP headers:
Authorization with a JWT session token created on demand and
XMLHttpRequest (basically narrows down the request type and improves security).
This is the server-side snippet that handles the session token. It resides in our main server file, where we define our spec-compliant GraphQL server, using an Express app as middleware. Within the configuration of our ApolloServer’s context property, you’ll see how we handle the auth header:
Notice how we leverage Shopify’s Node API to decode the session token and then to load the session data, providing us with the store’s access token. Fantastic!
Quick tip: To add more stores, you can switch out the store value in .env and run the Shopify CLI’s
app serve command!
Serving REST & GraphQL With Express
In our server-side code, we use the
apollo-server-express package instead of simply using
The setup for a GraphQL server using the express-specific package is quite similar to how we would do it with the barebones default package. The difference is that we apply the Apollo Server instance as middleware to an Express HTTP instance with graphQLServer.applyMiddleware( app ) (or whatever you named your instance).
If you look at the entire file, you’ll see that the webhooks and routes for the Express application are added after starting the GraphQL server. The advantage of using the
apollo-server-express package over
apollo-server is being able to serve REST and GraphQL at the same time using Express. Serving GraphQL within Express allows us to use Node middleware for common problems like rate-limiting, security and authentication. The trade-off is using a little bit more boilerplate, but since
apollo-server is a wrapper to the Express specific one, there’s no noticeable performance difference.
Check out the Apollo team’s blog post Using Express with GraphQL to read more.
Custom Client Wrappers
Here’s an example of custom API clients for data fetching from Shopify’s Node API, applying GraphQL and REST:
This allows for easier control of our request configuration, like adding custom
User-Agent headers with a unique header title for the project, including its npm package version.
Although Shopify generally encourages using GraphQL, sometimes it makes sense to use REST. In the admin app, we used it for one call: getting the products listings count. There was no need to create a specific query when an HTTP-GET request contains all the information required—using GraphQL would not offer any advantage. It’s also a good example of using REST in the application, ensuring developers who use the admin app as a starting point see an example that takes advantage of both ways to fetch data depending on what’s best for the situation.
Want to Challenge Yourself?
For full instructions on getting started with Marketplace Kit, check out our official documentation. To give you an idea, here are screenshots of the embedded admin app and the buyer app, in that order, upon completion of the tutorials in the docs:
More Stories on App Development and GraphQL:
For articles aimed at partners, check out our Shopify’s Partners blog where we cover more content related to app development at Shopify.
Kenji Duggan is a Backend Developer Intern at Shopify, working on the Strategic Partners team under Marketplace Foundation. Recently, when he’s not learning something new as a web developer, he is probably working out or watching anime
Wherever you are, your next journey starts here! If building systems from the ground up to solve real-world problems interests you, our Engineering blog has stories about other challenges we have encountered. Intrigued? Visit our Engineering career page to find out about our open positions and learn about Digital by Design.