Architecture Document for a Modern App

Dharmesh Mansata
5 min readSep 19, 2024

--

Designing a robust architecture for modern apps is critical to ensuring scalability, maintainability, and flexibility for future enhancements. In my latest project, I used Flutter alongside the BLoC pattern to build a structured, modular app with seamless state management. By focusing on best practices, such as a layered approach and clean separation of concerns, we were able to integrate features like Firebase Auth and RESTful APIs with ease. This architecture allows the app to adapt swiftly to future changes while ensuring optimal performance.

1. Cross-Platform Responsiveness

Flutter’s versatility across mobile, web, and desktop platforms makes it a fantastic choice for modern app development. For responsive design, we can leverage techniques like MediaQuery and AspectRatio, or create our own Screen Utility (like the one I built: Reference code). While there are great packages out there, like flutter_screenutil, I’m a firm believer in the DIY approach — why outsource when you can keep it in-house? Of course, platform-specific configurations and theme-based implementations can also be easily integrated for a seamless, consistent user experience. Reference code. After all, building custom solutions is half the fun in coding!

2. Secure Frontend-Backend Communication

Use https for all network call with help of alice [ https://github.com/jhomlala/alice ] you can verify each screen APIs. For more securing use JWT or refresh token method. For offline sensitive information store use flutter_secure_storage [Ref: https://pub.dev/packages/flutter_secure_storage ]. Please find below diagram for more:

Frontend-Backend Communication

3. Flexibility for Future Enhancements

The BLoC pattern is a powerhouse for handling complex logic, which is why we’ve implemented it extensively. In one of my projects, we used a layered architecture — Presentation, Domain, and Data — inspired by Uncle Bob’s Clean Architecture. For example, in the Reward Module, RewardBloc manages all the reward-related logic, processing events like EarnPoints and RedeemReward to ensure smooth user interactions. The beauty of this approach? Adding new modules, like a Transaction or Chat module, follows the same principle, making future enhancements almost effortless. The key is flexibility — entities act as the bridge between the domain and repository, ensuring they speak the same language. Think of it like building a LEGO set: once you have the foundation, adding new pieces is a breeze!

Uncle Bob’s Recommendations on Clean Code Architecture

4.Scalable Database Design

Our app is built to handle up to 100,000 users, so naturally, we opted for GraphQL — the cool middleman between the frontend and databases. Why GraphQL, you ask? Simple: it’s like ordering a combo meal instead of separate dishes. With just one API call, it fetches all the data you need, even if you’ve got a bunch of entity tables, minimizing those tedious round trips to the server.

Pairing GraphQL with the BLoC pattern is like getting the best of both worlds. We define resolvers in GraphQL to handle the database, while BLoC centralizes all the app’s business logic. And because we’re talking about 100,000 users, security’s tight — JWT secures our queries and mutations, with rate limiting for good measure. As for deployment? We’ve got versioning, feature toggles, and phased rollouts to keep everything smooth. It’s like launching a spaceship but with fewer explosions!

5.Separation of Business and View Logic

Every good app deserves a clear separation between business logic and view logic — after all, you wouldn’t want the brains of the operation tangled up in the presentation, right? That’s where BLoC and Provider come in. We chose this combo because it handles complex logic like a pro and keeps things scalable. With BLoC, the business logic stays neatly tucked away, completely independent of the UI. This way, when the app scales (and it will), we can make changes to the logic without touching the interface. It’s like having a personal chef: they handle the cooking, while you just enjoy the meal!

6.Deployment Strategy

Feature flags are like secret switches hidden in your app’s code — flick them on or off, and voilà! Features appear or disappear. In my case, I rolled out a reward system for just 5% of users using a simple JSON config file or Firebase Remote Config. It’s kind of like giving VIP access to a select few while the rest of the crowd waits at the gates.

Here’s the beauty of it: let’s say we’ve got a limited number of coupon codes. We launch to 5% of users, filtering by user ID or some unique identifier. Once those codes are gobbled up, we simply flip the feature flag switch, and boom! The reward system is down for maintenance (or as I like to call it, ‘coupon rehab’). If we need real-time updates, ably_flutter comes to the rescue with live events [Ref: https://pub.dev/packages/ably_flutter].

And when we push out a new version of GraphQL but the older app starts acting like a grumpy grandpa? No problem! Ably_flutter can clear local storage in real time, helping things run smoothly again. Plus, both Play Store and App Store have us covered with phased rollouts and Alpha/Beta testing. So, it’s all under control… most of the time!

And there you have it — building apps with scalable architecture, toggling features like a pro, and keeping everything under control (or at least pretending to!). Whether it’s handling reward rollouts for 5% of users or taming a grumpy old version of GraphQL, we’ve got the tools and techniques to make it happen.

If you’re itching to dive deeper and see all this in action, check out the seed repository I’ve put together: GitHub: dharmeshm10/seed. Just don’t forget to flip the right switches!

Thanks for sticking around till the end! If you have any questions, ideas, or just want to chat about all things Flutter and app architecture, feel free to connect with me on LinkedIn or catch me on Stack Overflow. I’d love to hear from you!

Until then, happy coding and remember — always flip the right switches!

--

--