It is a misconception that monoliths are only suitable for small projects or small teams. A well-built monolith can go a long way, which is what a modular structure and a good analysis bring. Modular Monoliths can be very powerful and work well for different sizes of projects. It is essential to consider the pros and cons of each approach when selecting the application pattern for a project. Maybe a cloud-native, serverless, microservices application is what your next project needs, but perhaps a well-designed Modular Monolith would achieve the same performance at a tremendously lower cost.To help you make those…
-
-
The modules of this application follow the previously discussed URI space: /{module name}/{module space}. Each module has a Constants file at its root that looks like this: namespace REPR.Baskets;public sealed class Constants{ public const string ModuleName = nameof(Baskets);} We use the ModuleName constant in the {module name}ModuleExtensions files to set the URI prefix and tag the endpoints like this: namespace REPR.Baskets;public static class BasketModuleExtensions{ public static IEndpointRouteBuilder MapBasketModule(this IEndpointRouteBuilder endpoints) { _ = endpoints .MapGroup(Constants.ModuleName.ToLower()) .WithTags(Constants.ModuleName) .AddFluentValidationFilter() // Map endpoints .MapFetchItems() .MapAddItem() .MapUpdateQuantity() .MapRemoveItem() ; return endpoints; }} With this in place, both modules self-register themselves in the correct URI…
-
The first thing to know about Modular Monoliths is that they are composed of different parts called modules. Each module is like a mini-app that performs a specific job. This job is related to a particular business capability. A business capability comes from the business domain and aims at a cohesive group of scenarios. Such a group is called a bounded context in DDD. Think of each module as a microservice or a well-defined chunk of the domain.That separation means everything we need to complete a specific task is in one module, which makes it easier for us to understand…
-
In a traditional monolithic architecture, we build the application as a single, indivisible unit. This leads to the functionalities being tightly coupled together, making it difficult to make changes or scale specific features. This approach makes creating a big ball of mud easier, particularly when the team invests little effort in domain modeling and analysis before and during development.On top of that, while this approach is simple and straightforward, it lacks the flexibility and scalability of more modern architectures. A monolith does not have to be indivisible, yet most end up this way because it is easy to create tight…
-
Before you begin: Join our book community on Discord Give your feedback straight to the author himself and chat to other early readers on our Discord server (find the “architecting-aspnet-core-apps-3e” channel under EARLY ACCESS SUBSCRIPTION). https://packt.link/EarlyAccess In the ever-evolving software development landscape, choosing the right architecture is like laying the foundation for a building. The architecture dictates how the software is structured, impacting its scalability, maintainability, and overall success. Traditional monolithic architecture and microservices have long been the dominant paradigms, each with advantages and challenges.However, a new architectural style has been gaining traction—Modular Monoliths. This approach aims to offer the…
-
In this scenario, we have a legacy application to decommission and a microservices system to which we want to connect some existing capabilities. To achieve this, we can create one or more adapters to migrate all features and dependencies to the new model.Here is a representation of the current state of our system: Figure 19.37: The original legacy application and its dependencies The preceding diagram shows the two distinct systems, including the legacy application we want to decommission. Two other applications, dependency A and B, directly depend on the legacy application. The exact migration flow is strongly dependent on your…
-
This section explores some advantages and risks of separating a data store’s read and write operations using the CQRS pattern. Benefits of the CQRS pattern Potential Risks of using the CQRS pattern Conclusion CQRS helps divide queries and commands and helps encapsulate and isolate each block of logic independently. Mixing that concept with serverless computing or microservices architecture allows us to scale reads and writes independently. We can also use different databases, empowering us with the tools we need for the transfer rate required by each part of that system (for example, frequent writes and occasional reads or vice versa).Major…