Slaying the Monolith: API Implementation and Modularization in Android
Article Summary
Sean Coyle from ASOS reveals how they're dismantling their Android monolith using a pattern that slashes recompile times. The secret? Splitting every feature into API and implementation modules.
ASOS's Android team faced the classic monolith problem: slow builds, tangled dependencies, and features that couldn't evolve independently. Coyle walks through their modularization strategy using the API/Implementation pattern, a dependency inversion approach that separates what modules do from how they do it.
Key Takeaways
- API modules expose interfaces only; implementation changes don't trigger full app recompiles
- Pattern follows SOLID's dependency inversion: high-level modules stay stable, low-level modules change freely
- Start with 'leaf nodes' like domain models for easiest extraction from monolith
- Use 'implementation' over 'api' in Gradle to promote encapsulation and faster builds
- Trade-off: Added complexity from managing multiple modules can outweigh benefits in smaller apps
The API/Implementation pattern enables independent feature evolution and faster compile times by decoupling module contracts from their concrete implementations.
About This Article
ASOS's Android app became a monolith after years of adding features. This created real problems: builds took too long, code couldn't be reused easily, and features like authentication, image processing, and data analysis were tangled together without clear boundaries.
Sean Coyle's team split each feature module into two parts using the API/Implementation pattern. One part is the API module with interfaces and contracts. The other is the implementation module with the actual code. Dependency injection frameworks like Dagger or Hilt connect them together.
When someone changes an implementation module, it no longer forces a full recompile of everything that depends on it. Other modules only talk to the stable API contracts, so compile times dropped significantly. Teams can now work on features independently without stepping on each other's toes.