• Backend for Frontend pattern - Challenges and Pitfalls - Exams of ASP.NET - Managing the shopping cart - Revisiting the CQRS pattern

    Challenges and Pitfalls – Modular Monolith

    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…

  • Challenges and Pitfalls - Exams of ASP.NET - Managing the shopping cart - Revisiting the CQRS pattern - The message broker

    Sending HTTP requests to the API – Modular Monolith

    Now that we have a working modular monolith, we can reuse similar HTTP requests than the previous versions.At the root of the REPR.API project, we can use the following: A new outcome in this API compared to the previous versions is when we try to add a product that does not exist in the catalog to our basket, like the following request: POST https://localhost:7164/basketsContent-Type: application/json{    “customerId”: 1,    “productId”: 5,    “quantity”: 99} Since the product 5 does not exist, the API returns the following: HTTP/1.1 400 Bad RequestContent-Type: application/problem+json{  “type”: “https://tools.ietf.org/html/rfc9110#section-15.5.1”,  “title”: “One or more validation errors occurred.”,  “status”: 400,  “errors”:…

  • Exams of ASP.NET - Managing the shopping cart - Revisiting the CQRS pattern - The message broker - What is a Modular Monolith?

    Inside the aggregator – Modular Monolith

    The aggregator application is like an empty shell that loads the other assemblies and configures the cross-cutting concerns. It references the modules, then assembles and boots the application. Here’s the first part of the Program.cs file: using FluentValidation;using FluentValidation.AspNetCore;using MassTransit;using REPR.API.HttpClient;using REPR.Baskets;using REPR.Products;using System.Reflection;var builder = WebApplication.CreateBuilder(args);// Register fluent validationbuilder.AddFluentValidationEndpointFilter();builder.Services    .AddFluentValidationAutoValidation()    .AddValidatorsFromAssemblies(new[] {        Assembly.GetExecutingAssembly(),        Assembly.GetAssembly(typeof(BasketModuleExtensions)),        Assembly.GetAssembly(typeof(ProductsModuleExtensions)),    });builder.AddApiHttpClient();builder.AddExceptionMapper();builder    .AddBasketModule()    .AddProductsModule();builder.Services.AddMassTransit(x =>{    x.SetKebabCaseEndpointNameFormatter();    x.UsingInMemory((context, cfg) =>    {        cfg.ConfigureEndpoints(context);    });    x.AddBasketModuleConsumers();}); The preceding code registers the following: The container we register those dependencies into is also used for and by the modules because the aggregator is the host. Those dependencies are shared across…

  • ASP.NET Certifications - Exams of ASP.NET - Managing the shopping cart - Revisiting the CQRS pattern - The message broker - What is a Modular Monolith?

    Consuming the events from the basket module – Modular Monolith

    The basket module wants to cache existing products. We can achieve this in different ways. In this case, we create the following Product class that we persist in the database: namespace REPR.Baskets.Data;public record class Product(int Id); To make use of it, we must expose the following property from the BasketContext class: public DbSet<Product> Products => Set<Product>(); Then, we can start to leverage this cache. Firstly, we must populate it when the catalog module creates a product and remove that product when deleted. The ProductEventsConsumers class handles both events. Here’s the skeleton of this class: using REPR.Products.Contracts;namespace REPR.Baskets.Features;public class ProductEventsConsumers :…

  • ASP.NET Certifications - Backend for Frontend pattern - Exams of ASP.NET - Revisiting the CQRS pattern - The message broker - What is a Modular Monolith?

    Sending events from the catalog module – Modular Monolith

    For the catalog to communicate the events that the basket module needs, it must define the following new operations: Here are the API contracts we must create in the REPR.Products.Contracts project to support those two operations: namespace REPR.Products.Contracts;public record class CreateProductCommand(string Name, decimal UnitPrice);public record class CreateProductResponse(int Id, string Name, decimal UnitPrice);public record class DeleteProductCommand(int ProductId);public record class DeleteProductResponse(int Id, string Name, decimal UnitPrice); The API contracts should look very familiar by now and are similar to those from previous chapters. We then need the following two event contracts: namespace REPR.Products.Contracts;public record class ProductCreated(int Id, string Name, decimal UnitPrice);public record…

  • ASP.NET Certifications - Backend for Frontend pattern - Challenges and Pitfalls - Exams of ASP.NET - The message broker - What is a Modular Monolith?

    The message broker – Modular Monolith

    To handle the integration events between the catalog and the basket modules, I decided to pick MassTransit. To quote their GitHub project: MassTransit is a free, open-source distributed application framework for .NET. MassTransit makes it easy to create applications and services that leverage message-based, loosely-coupled asynchronous communication for higher availability, reliability, and scalability. I picked MassTransit because it is a popular project with 5,800 GitHub stars as of 2023 and supports many providers, including in-memory. Moreover, it offers many features that are way above our needs. Once again, we could have used anything. For example, MediatR could have also done…

  • ASP.NET Certifications - Backend for Frontend pattern - Challenges and Pitfalls - Exams of ASP.NET - What is a Modular Monolith?

    The URI space – Modular Monolith

    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…

  • Challenges and Pitfalls - Exams of ASP.NET - The message broker - What is a Modular Monolith?

    Identifying the modules – Modular Monolith

    Now that we have identified the entities, it is time to map them into modules. Let’s start with the following diagram:  Figure 20.4: Modules (bounded context) separation and entities relationships.   As expected, we have a product catalog, a shopping basket, and a customer management modules. What’s new here is the relationships between the entities. The catalog mainly manages the Product entity, yet the shopping basket needs to know about it to operate. The same logic applies to the Customer entity. In this case, the shopping basket only needs to know the unique identifier of each entity, but another module…

  • ASP.NET Certifications - Backend for Frontend pattern - Exams of ASP.NET - Managing the shopping cart - Revisiting the CQRS pattern

    Planning the project – Modular Monolith

    Planning is a crucial part of any software. Without a plan, you increase your chances of building the wrong thing. A plan does not guarantee success, but it improves your chances. Overplanning is the other side of this coin. It can lead to analysis paralysis, which means you may never even deliver your project or that it will take you so long to deliver it that it will be the wrong product because the needs changed along the way and you did not adapt.Here’s a high-level way to accomplish planning a Modular Monolith. You don’t have to execute all the…

  • ASP.NET Certifications - Backend for Frontend pattern - Challenges and Pitfalls - Exams of ASP.NET

    Key Components of a Modular Monolith – Modular Monolith

    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…