Kotlin Multiplatform at Glovo
A story from my personal experience of working for more than a year with Kotlin Multiplatform at Glovo.
First, a bit of Kotlin history at Glovo
I joined Glovo around 2 and half years ago, and at that moment (as you may imagine) only Androiders were the ones using the language in production.
I remember my web colleague Huw (nice person by the way) starting the #kotlinize-glovo Slack channel to raise awareness internally about its features. Java Backend had a mixture of Play Framework, Lombok and Spring to add something else into that combo.
Our first Kotlin contribution in the backend was a buildSrc plugin logic that I borrowed from our Android project.
At that moment, it was just a matter of time to let the industry catch up and we weren’t the exception. I’m proud to say that Glovo launched its first pure Kotlin microservice a few months ago, boosted by some talented new joiners who had experience working with Kotlin. And with that milestone, we archived our #kotlinize-glovo channel. Hurray!
The “Back To School Friday” factor
At Glovo we have Friday afternoon allocated for ourselves, so we can focus on those tiny (or not so tiny) projects that we’d like to try but never have time to.
We can use our Fridays to learn. It doesn’t matter exactly how: by reading, taking an online course, etc.
In my case, I’m one of those people who learn by experimentation. So I dedicated several Fridays to this project, which I can say now, almost 1 year and a half later, was a success but still has some caveats. I’ll dive deeper later, don’t worry.
Our Use Case: Standardize Tracking Events
Glovo is proud of being a Data-Driven company, which means that we make our business decisions based on hard evidence provided by the data we collect.
We have two main apps, Customer and Courier, and each of them has different platform versions: Android, iOS, and Web.
As you may think, each developer had to implement the tracking logic on its own which eventually produced discrepancies between the apps and the platforms.
As an example, we had events coming from Android with cityName and from iOS with city_name
The business goal for this project was to standardize the events definitions and their generation (on the apps) to assure the data we collect is trustable, reliable, and mostly the same between the platforms.
Given those requirements, I proposed KMP as the underlying technology because it would allow us to:
- Have a unified source of trust for our events
- Share business logic across all apps
- Ensure events’ raw serialized data is the same across all apps
The only problem is that you can’t adopt KMP on projects already established (for iOS and web). In my other post, I address the reasons why in the “The scale restriction” section.
So, for this to work, we’ll have to produce some native artifacts for each platform: a CocoaPod for iOS and an NPM package for web
I’d like to give a special mention to Alena, a brilliant Product Manager we had, thanks to whom, before I even realized, my initial PoC of a Multiplatform library had become the seed of our fresh new cross-platform Tracking Events library
Drafting the concept of a Multiplatform Native library
The idea was simple, but a big challenge. If we can manage to produce native artifacts for each platform, then we can just consume them like any regular iOS’s CocoaPod or NPM package but with KMP code inside it.
So I undusted my old Ruby/JavaScript skills, read a lot of CocoaPods and NPM technical specs, and started to write a viable process to produce them.
The solution consisted of a core library containing the base KMP code and using YAML to define our Tracking Events. The build process validates them and then generates Kotlin classes that represent the events we wanted to track.
The whole project is packaged and distributed as native libraries for each platform. We added observability around the events to keep track of the deployment status on the frontends, and a Confluence page to have them documented for everyone in the organization who queries for them.
Backend was left out to reduce the scope, but as with any JVM-based project, integrating it won’t represent a big challenge. Actually, we’ll likely take it up again shortly
This was pretty much the idea that we had in mind on how the library is supposed to be consumed by the frontends:
The project was ambitious, but we had a dedicated team to work over a whole quarter and we delivered it.
Lessons learned
- KMP is great for greenfield projects, but adopting it on established traditional projects can have a big impact. Not just in code, but in the skills your team is going to need to work and perform with this new technology. This is probably the biggest barrier to overcome.
- The “Multiplatform Native library” concept is something not yet explored (at least that I’m aware of). Yet, it allowed us to overcome the barrier I’ve just mentioned in the previous point.
Anyway, scaling this approach to other libraries without any official support for it is a risk. That’s why we are not spreading this approach to new code (at least for now).
Conclusions
I’m proud to say that one year and a half later, this “experimental” project is considered a success and innovates on what could be the next generation of non-intrusive cross-platform coding standards.
It has been a long journey filled with challenges, searches, and learnings that I’ll cover in my next article Publishing native artifacts from a Kotlin Multiplatform project
Kotlin Multiplatform at Glovo was originally published in Glovo Engineering on Medium, where people are continuing the conversation by highlighting and responding to this story.