Way of Development in Modular Monoliths Project: Shared -> Modules -> API
We’re going to dive into the development path for our EShop Modular Monolith project.
This is a crucial topic because following a structured development path ensures that our application is robust, scalable, and easy to maintain. Let’s break down the approach we’ll be using to build our application, step by step. 🌟
Development Path Overview
Our project is organized into three main folders:
- Bootstrapper (API)
- Modules
- Shared
We’ll follow a specific development path to make sure that we build our application systematically and efficiently. The path we will follow is: Shared -> Modules -> API. Let’s explore what each of these steps involves.
1. Shared Components Development 🛠️
The first step in our development path is to create Shared Components. These are the foundational building blocks that will be used across multiple modules in our application.
- Common Classes and Utilities: These include basic utility classes, helper functions, and common data structures that are shared across the application.
- Abstractions: We’ll define interfaces and abstract classes that encapsulate shared behaviors and contracts. These abstractions provide a consistent way to interact with different modules.
- Cross-Cutting Concerns: This includes functionalities like logging, validation, and exception handling that are needed throughout the application. By centralizing these concerns, we avoid code duplication and ensure consistency.
By starting with shared components, we establish a strong foundation for our modules, ensuring that each module can leverage these common elements. This step reduces duplication and promotes consistency across the application. 🎯
2. Module Development 🔍
Once we have our shared components in place, we move on to developing each module. Each module will be developed using the following path: Domain -> Infrastructure -> Application Use Cases -> API.
Let’s break this down:
Domain 🌐
- The Domain layer is the heart of our module. Here, we define our domain entities, domain events, and domain rules. This layer represents the core business logic and rules that are specific to each module.
- For example, in our Catalog Module, the domain layer will include entities like
Product
andCategory
, as well as any business rules or events associated with them.
Infrastructure 🏗️
- In the Infrastructure layer, we implement all the tasks related to data access and persistence. This includes setting up Entity Framework Core (EF Core) for database interactions, configuring entities, and managing migrations.
- This layer acts as a bridge between our domain model and the underlying database, ensuring that our domain remains decoupled from data storage concerns.
Application Use Cases 🧩
- The Application layer is where we define use cases and business logic that orchestrates interactions between the domain and infrastructure. We’ll use patterns like CQRS (Command Query Responsibility Segregation) and Mediator to structure this layer.
- This layer handles the execution of specific business actions, ensuring that the business rules are applied consistently and correctly.
API 🌍
- Finally, we expose the module’s functionality through RESTful APIs in the API project. This is where we define endpoints that external systems can use to interact with our application.
- For instance, in our Catalog Module, the API layer would expose endpoints for creating, updating, retrieving, and deleting products.
3. API Bootstrapper📡
After developing the shared components and modules, the final step is to integrate everything into the API project. This project serves as the entry point for our application, exposing all the functionalities of our modules through RESTful APIs.
- Registering Services: We’ll use dependency injection (DI) to register services from each module into the API project. This ensures that the API can access and use the functionality provided by each module.
- Setting Up Routes and Endpoints: We’ll define the routes and endpoints for our API, mapping HTTP methods to specific actions in our modules.
- Configuration and Middleware: We’ll configure middleware components like authentication, authorization, logging, and error handling to ensure that our API is secure, performant, and reliable.
By following this structured approach, we ensure that our application is built in a modular, scalable, and maintainable way. Each layer builds on the previous one, creating a robust architecture that’s easy to extend and evolve. 🚀
Visualizing the Development Path
Here’s a visual representation of our development path:
Shared -> Modules -> API
Within each module: Domain -> Infrastructure -> Application Use Cases -> API
This approach ensures a clear separation of concerns and promotes modularity, making our application easier to manage and scale over time. By building in this way, we can focus on creating high-quality, maintainable code that meets the needs of our business and our users. 🎨
Conclusion 🎬
In this article, we’ve outlined the Way of Development: Shared -> Modules -> API for our EShop Modular Monolith project. By following this structured approach, we ensure that our application is modular, scalable, and maintainable. We started with shared components, moved on to developing individual modules, and finally integrated everything into the API project. 🚀
This is step-by-step development of reference Modular Monoltihs Architecture on .NET used ASP.NET Web API, Docker, PostgreSQL, Redis, RabbitMQ, Keycloak, Seq, MassTransit, Entity Framework Core, CQRS, MediatR, DDD, Vertical Slice Architecture and Outbox Pattern implementation with using latest features of .NET 8 and C# 12.