logoDroidKaigi Ninjas
DroidKaigi 2021

DroidKaigi 2021

Introducing a Multi-Module Configuration in a Fast-Growing Service

coconala Inc.
Oct 15, 2021

This is an English translation of the original Japanese article.

In recent years, Android has increasingly been seeing apps built through a combination of multiple modules. This approach is known as a multi-module architecture, and we at coconala have started working to adopt it, too. This article shares our efforts of transitioning from a monolithic to a multi-module configuration.

Issues of a monolithic configuration

coconala provides a market on which people can sell or purchase knowledge-, skill-, and experience-based services. More than 400,000 services are available in over 450 categories, ranging from business to personal affairs. Through the market, users can consult with or make requests to experts for diverse situations, be it solutions for business issues or distress and trouble in private life.

After releasing our first Android client app in 2017, we have thus far made at least 200 releases with various feature additions and improvements. Though initially simple and easy to handle, as the product grew, the monolithic app module configuration gradually became bloated and started to stretch out our build time.

Early on, I was the only person tasked to develop the Android app. But over time, more development members came on board, speeding up feature-adding and improvement processes. Faster product growth is of course a major advantage, but members started experiencing difficulty in grasping the overall picture. Source code conflicts became a frequent problem, creating a disadvantage that involved complex dependency.

That’s where the multi-module architecture came into play. Splitting modules to eliminate interdependency allows for members to advance their development efforts without worrying about the impact on other features. This can also make catching up easier when working on features developed by another member, because you just have to focus on a specific module.

For further growth of our product, we need a configuration that can withstand change. As such, we decided to simplify the app through module-splitting and forcing source code dependency.

Best practices for the coconala Android app

For the module-splitting process, we studied a host of cases in which a multi-module configuration was adopted for an Android app and diagnosed the advantages and disadvantages of splitting by layer and feature. We also re-classified the coconala Android app’s features to sort out their relationship.

When finalizing our module configuration, we especially focused on exploring best practices for the coconala Android app. For technical decisions, we need to think about whether a tool or approach—even if they are a de facto standard in the world of Android app development—matches the characteristics of our product, coconala. This same mindset applied to module-splitting, too.

The final result of module-splitting

For the app, we ended up with the below module configuration after considering inter-feature relationships and the handling of common code. The app basically splits modules on a feature basis, while also splitting modules per layer for common-use layers.

Module configuration of coconala Android app

We adopted a per-feature split, considering that the plurality of coconala’s primary features would benefit more from a multi-module configuration than a layer-basis split. We also had in mind future support for Play Feature Delivery. Users of coconala do not deal with some features prior to taking specific actions, such as putting up or purchasing a service. This means that with Play Feature Delivery, users can save file space compared to installing a fully-featured AAB from the beginning.

Another characteristic aspect is that the configuration independently splits modules with all model classes from modules storing .proto files. Some APIs use a gRPC communication framework, so the app uses the .proto file-storing repository as a library module, harnessing a git submodule.

That’s our current module configuration. But the best practice will likely shift as the product and the team’s situation changes going forward. When such changes happen, we hope to engage in discussions as a team and flexibly search for solutions.

Issues we faced in introducing the module configuration

We faced an issue after determining the module configuration and moving into the introduction phase. Initially, we planned to split modules of the relevant and common features within a project that was meant for replacing existing features. But we realized that another large project and an overall service rebranding project was getting underway at around the same time. Some team members suggested rescheduling, but after much debate we decided to go on to introduce the multi-module configuration, at which point branching became an issue.

To advance each project while carrying forward multi-modularization, we first created a base branch for module splitting. This consisted of color palettes redesigned in the process of the rebranding and module-splitting of common features.

Base branch for module-splitting

Individual pull requests are submitted to the base branch for details in the base branch. But this approach requires constant caution to prevent conflict, and on top of that, it created problems (e.g. features not being fully developed in each project). Setting tentative rules for the code review provided some improvement but no dramatic benefits.

My opinion is that this approach—under which we created a base branch for module-splitting—was a failure. But there was an unexpected by-product. The need to make decisions each time about module-splitting and code-merging destinations pushed team members to communicate more closely on such topics as the granularity of the module-splitting. The development initiative was no easy task, but as a result of active communication efforts, no misunderstanding occurred among team members. This contributed to our confidence in moving forward as a team.

In conclusion

This article shared about efforts to adopt a multi-module configuration for our coconala Android app. Developing features and multi-modularizing at the same time was a tough process, but we gained various learnings and lessons. There’s still a long way to go; we just recently became capable of smoothly working on multi-modularization as part of our development effort. Going further, we plan to actively use the new module configuration to not only develop new features but also improve existing ones.

The coconala Android development team has been taking on various challenges—apart from multi-modularization— and will keep working to continuously provide good products in a continuous manner.

We’re looking for people to come work with us (see our engineer recruitment website). Contact us if you’re interested!

About the author

Tomonori Nakada

Android team, App Development Group, coconala Inc.

A graduate of Tokyo Denki University, Tomonori Nakada acquired experience in business-related mission-critical systems at Infotec Inc. He then moved on to DNP Communication Design, starting his career there as an Android app engineer. He took up his current post in September 2017.

coconala Inc.
coconala Inc.
coconala runs its namesake platform, one of Japan’s largest skills market in which people can offer or purchase such assets as knowledge, skills, and experience. The company was listed on the Tokyo Stock Exchange MOTHERS Market on March 19, 2021.
Go to Corporate Site