Flutter at Scale - 10 Lessons Learned From Building an Enterprise Flutter App
Building an enterprise-scale application requires a specific approach not only toward the system architecture but also toward organizing the team and the code they create. After the architecture, organization, and communication are pivotal to secure yourself a smooth path towards the milestone on the roadmap for large-scale projects.
In this study, we would like to share our thoughts and experiences from our two-year-long journey of developing a very large banking mobile application for Credit Agricole using Flutter working with 30 Flutter Devs spread across 15 teams. Check our case study of this project.?
Why is building an enterprise app so much different than for a startup or small scaleup? When we’re talking about large projects, we mean a project spread across different teams, companies, and business domains because development is only a small part of the whole. In small projects, we often know every developer who’s working with us. There’s even a huge possibility that a backend dev that serves us some API sits next to us the whole time. It’s much easier not to worry about some issues when we don’t encounter them. In large-scale apps, we are rarely in a situation where, while building a powerful contract-based asynchronous communication with our backend, we can just get some coffee with the backend team and discuss everything.
So, in large projects, we just want to help ourselves - to deal with multiple obstacles that we cannot directly resolve - obstacles that are not only related to the code. Let’s see how we can wrap our heads around this level of complexity in terms of code and, most of all, in communication.
First and foremost, the code ownership. If nobody owns the code, nobody cares. You can argue that feature squads should take care of the ownership of whatever they deliver. But what about some common areas? What about the general concepts and libraries and their maintenance? The battle-tested solution that really works is to create an “artificial” technical team who OWNS all important architectural decisions and is responsible for keeping the app up and running.?
Secondly, large-scale apps require a specific approach to the code structure. The wrong choice can corrupt the whole project in the long run. The typical choice we have is between layer-based, horizontal slicing versus a column-based, vertical, feature-driven approach. Yet, in the case of an enterprise, what we should never forget is Conway’s Law, which says that the code structure will eventually resemble an organization's structure. Getting back to the main question: have you seen the organization divided into those horizontal layers??
Moreover, when building a large project with a complex structure, you will find yourself in a position where managing packages can become quite a task. It is hard to identify exactly a threshold when it happens, so it’s better to follow good practices from day one and implement a tool like Melos from Invertase to manage your Dart projects with multiple packages.
Communication between development units is always to be taken care of. Once you build the facade of separate code territories owned by squads, it is to build silos. Still, more often than not, they need to communicate with each other, and communication should have its rules. Some events in the system will require synchronous communication, whereas, with others, you can allow asynchronous communication. Data streams and some auto-updating mechanisms can add even more complexity to that.
领英推荐
Proper navigation is at the heart of a good user experience. It should be the major objective to guarantee a smooth transition across whatever code structure we build if this is required by the user journey. It may be hard to achieve in an environment where code ownership principles and code separation practices are in place. Yet, it is possible if you introduce a proper separation of navigation targets from the page implementation and allow passing the context between the pages.
In the case of an enterprise app, going global is often a must. Therefore, from day one, you should think about the proper localization policy and what you are going to adjust while expanding to new markets. Some changes can go as far as changing the entire layout for a right-to-left approach, typically, e.g., for Arabic countries. However, even without those complex transitions, you still need to think about the proper Translation Management System, which will help you to manage your l10n files. And be careful with your research, especially with Flutter .arb files, which are not so popular in the l10n world. You’d better be sure that the tool you are going to pay for is compatible with your development.
Enterprise solutions are typically associated with high quality. They should be bullet-proof and battle-tested. But are they? What can you do to ensure that there are no regression bugs with the first release? Making the QA go manually through the app can work at the beginning. However, the more complex the app becomes, the less possible it is to run even the smoke tests automatically. What you need are automated, end-to-end UI tests. Until recently not available for Flutter if you were to transition between native and Flutter screens. However, with the arrival of Patrol, the open-source UI Testing Framework for automating the test, this is no longer a problem. Patrol is the final building block to make Flutter enterprise-ready.??
We all know that somewhere there is a normal JSON (or XML)-based API. Probably someone will like to call it a REST API, REST-ful, REST-ish, or just “an'' API. Or GraphQL one. That does not really matter. No matter what API style you use, it still requires a non-negligible amount of work. And if you want to avoid the mismatch between the frontend and the backend contracts, even when they are generated with OpenAPI schema, it will be your growing concern. So, our solution to that is “strongly typed contracts.” Delegating the responsibility for the contracts to the backend team has many benefits. If you add to that the possibility of generating the contracts automatically, then you are ready to conquer the world no matter how big the project is.
In the enterprise world, you build the things which last. Therefore you cannot avoid the legacy. Instead of hiding from it, you should understand how to tame it. One possible solution is to deprecate things. However, saying is one thing, and execution is the other. This comes with proper communication and robust monitoring.
Last but not least, we cannot forget the overall visual satisfaction users should experience while interacting with the app. In order to ensure that while working in several separated squads, all developers have to use unified controls and widgets that are standardized on a project level. This can be achieved with a proper Design System, which not only helps to provide a consistent color palette and consistent approaches to similar user stories but also ones a door for quick implementation of light/dark modes, allows for handling accessibility, and brings a number of additional benefits.
If you are further interested in exploring this set of best practices for building enterprise apps in Flutter, take a look at our White Paper: Flutter for Enterprise. The entire article by Mateusz Wojtczak , the Head of our Flutter Team at LeanCode, you can find on our blog.
UI/Web Developer ???? | Next.js/React Expert | WordPress | Crafting Engaging User Experiences with Every Pixel
1 年This is a great article! I'm always interested in learning more about how to build enterprise applications.