Migrating our Apple WatchOS Commerce App to GraphQL
In today’s constantly-connected era, we see many commerce avenues available across all existing platforms: from traditional websites and mobile apps that we’re used to, to voice assistants, IoT buttons, and last but not least — wearables. Even though not all platforms bring equal traffic and revenue, for many players it is important to have a presence on as many devices as possible.
With that, it’s important to take full advantage of what every platform / device family has to offer. While a simple IoT button is really useful for reordering a detergent, an app on a wearable device can do more — such as letting customers update order statuses, perform quick actions on past orders, get recommendations, new products, and maybe even a quick add-to-cart action in case something catches customer’s eye.
Moving our watch app from REST API to GraphQL
If you’re looking for a popular wearables platform to get started with, Apple Watch might be the right choice, mostly because the last year’s reports stated that Apple Watch is inches away from having a 50% market share in wearables. We have included an Apple Watch app along with our demo iOS app, Sunrise, which serves as a showcase of how you get easily get started with commercetools API and the Swift SDK.
Initially, the watch app used the same REST API as its iOS counterpart. You can check out the beta version via Apple’s TestFlight app. Even though the app was fully functional, some API interactions took longer-than-ideal times to complete and decode the data received into model objects. It turns out that many entities from the e-commerce domain tend to be bigger in size, mostly because of the business logic they carry.
A good example is a product projection, which carries information about all product variants, pricing conditions for each variant, tax info, reviews and ratings, etc. Even though the design for the watch doesn’t include many of these items, there is no simple way to exclude them when using a REST API.
That’s when we decided to migrate over to GraphQL API — commercetools has supported GraphQL since 2016 and was the first commerce platform to have done so. We’re working on getting it out of beta, though it has already been used across many production applications today.
Which framework should I use?
The first step is to decide whether you would like to use a watchOS framework like Apollo, which can help with generating models from your queries, and provide caching support if your application needs it. For the Sunrise watchOS app, we were already using the commercetools Swift SDK, which provided the models needed out of the box, so we decided not to include another dependency to the project. In this case, the trade-off is to at least write the top-level models matching the queries, and then use the structs from the SDK for lower-level fields.
For encoding and decoding, and performing network tasks, we used the commercetools Swift SDK, which was already a part of the project — a good choice since it meant fewer changes. However, when starting from scratch and using an API which doesn’t provide an SDK, you might want to use features provided by the GraphQL framework, like Apollo.
The GraphQL performance difference
The improvements are noticeable even without looking at the numbers. Since the newest devices like the Apple Watch series 4 and 5 have better hardware, we decided to compare the app on the older series 2 watch, running watchOS 6.1.3. This way, we’d be able to observe even more pronounce differences in performance.
We loaded the ‘My Orders’ screen, which shows the 5 most recent orders. With REST API implementation, we had to retrieve 5 Order objects, which contain a lot of information the watch doesn’t need, and averaged a loading time of 2000ms. This query that the new GraphQL version uses resulted in a load time of just 600ms (3 times faster!), since it retrieves only the necessary data we want. These timings include executing the network task, processing, and decoding the response.
Similarly, for the product overview screens, where we retrieve five products at a time, the loading time (including decoding) was significantly faster with GraphQL — averaging around 3100ms with REST API but clocking under 1000ms with GraphQL.
We’ve seen great GraphQL adoption over the years and any production products are successfully using it these days. However, it’s still underrated in wearables and lower-end devices which have probably the most to gain from it. In our case, and generally for majority of commerce apps, where the nature of business logic requires big domain objects, the improvements are definitely noticeable. If you would like to find out more about the demo app you can head to the Github page, or try it out using the TestFlight invite.