FAQs - IIIA-KO/Lanka GitHub Wiki
Q: What is the current status of the project? Is it production-ready?.
A: Lanka is currently in active development. The core backend modules (user auth, campaigns, etc.) are under construction and key functionalities are being implemented. It is not yet production-ready – for instance, the front-end is still in planning and certain features like user login are forthcoming. However, the architecture and groundwork are in place. Developers can run the platform locally and even use the available features, but for end-users a polished release will come once development completes the planned features and thorough testing is done.
Q: Is Lanka a monolithic application or microservices?.
A: Lanka is a modular monolith. This means it’s a single application divided into multiple feature-modules internally. All modules run in one process and share the same database, which simplifies development and deployment. However, the internal design (with clearly separated domains and an event-driven communication via an internal event bus) mimics many benefits of a microservices architecture (loose coupling, independent development of modules). The presence of a Gateway and the way modules communicate means that if needed, in the future each module could be extracted into its own service with minimal changes. The current approach was chosen to avoid the overhead of managing multiple services early on while still keeping the codebase organized.
Q: How do modules communicate with each other within the monolith?.
A: Modules communicate asynchronously using integration events on a central event bus (RabbitMQ via MassTransit). For example, when the Users module registers a new user, it might publish a UserRegisteredIntegrationEvent. Other modules, like Campaigns (which might need to create a Blogger profile for the new user in its own context), subscribe to that event and react accordingly. This publish/subscribe mechanism via RabbitMQ decouples the modules – they don’t call each other directly, they just emit or listen for events. The Outbox/Inbox patterns are used to ensure that this communication is reliable and that events aren’t lost or duplicated. Essentially, even though it’s a single application, we treat inter-module interactions as if they were separate services communicating over a message broker.
Q: Why use RabbitMQ and MassTransit if it’s a single application?.
A: This is a deliberate design to enforce loose coupling and reliability. By using RabbitMQ (a message broker) and MassTransit, the project benefits from **distributed system patterns88 (asynchronous messaging, retries, dead-lettering) from day one. Even in a monolith, this can be useful – for example, if one part of the system is temporarily failing or slow, it doesn’t bring down the others; messages will queue up and be processed when ready, which improves resiliency. MassTransit also provides a convenient abstraction for message handling in .NET, and using RabbitMQ means the system can scale horizontally (multiple instances consuming messages) in the future. Moreover, since the plan is to potentially have a separate front-end and other integrations, having a message infrastructure can ease integrating additional services. In short, it’s about building a future-proof foundation: today a monolith, but with messaging that could support a transition to microservices or simply more robust internal decoupling.
Q: How is data stored and managed across modules?.
A: Currently, all persistent data (for all modules) is stored in a PostgreSQL database. The application likely uses a single database with tables namespaced or grouped by module. Domain-driven design patterns like Aggregate Root and Unit of Work are used to ensure each module’s data integrity. For example, the Campaigns module might have tables like Campaigns
, Offers
, Pacts
, etc., and the Users module has Users
and related tables. Each module’s repository or data access layer only deals with its own tables (to maintain a boundary). In code, transactions are typically scoped to a module’s operations (though integration events allow eventually consistent updates between modules). The Unit of Work (often via EF Core’s DbContext) ensures all changes within a module for a single operation either commit or rollback together. There isn’t a separate database per module (which is typical for true microservices), but the design could evolve in that direction if needed, thanks to the clear separation.
Q: Where can I learn more about the design decisions and patterns used in Lanka?.
A: The repository contains a rich set of documentation in the docs folder, including an Architecture Decision Log (ADL). The ADLs are numbered markdown files that record the rationale behind important decisions. For example, there is an ADL about adopting an Event-Driven Architecture with Outbox/Inbox. There are also a series of documents in docs/catalog-of-terms that explain fundamental concepts (Aggregate Root, Domain Event, Integration Event, Unit of Work, etc.) in the context of this project.