Consuming Discount Grpc Service From Basket Microservice with .NET 8

Mehmet Ozkaya
4 min readMar 25, 2024

--

We are going to Consume Discount Grpc Service From Basket Microservice When Adding Cart Item into Shopping Cart To Calculate Final Price.

Basket Microservice Consume Discount Grpc Service

I have just published course — .NET 8 Microservices: C# 12, DDD, CQRS, Vertical/Clean Architecture.

The Big Picture 🌐

We’ll focus on integrating the Discount Grpc Service into the Basket Microservice. Specifically, the Basket Microservice will utilize the Discount Grpc Service to apply discounts when items are added to the shopping cart, calculating the final price.

Making the Connection 🔗

Our Basket Service is stepping up its game by turning into a gRPC client, ready to fetch those sweet deals for you. Think of it as having a savvy shopping assistant right in your cart, always on the lookout for discounts.

Gear Up for Integration 🛠️

We’ve fine-tuned the Program.cs file in our Basket Service to introduce it to the Discount Grpc Service. It's like setting up a direct hotline between your cart and the discount vault, ensuring no deal goes unnoticed.

When client add item into shopping cart, Basket microservice will consume this discount grpc services, in order to get latest discounts on that product item. The Basket Microservice will act as a gRPC client to consume services exposed by the Discount Grpc Service.

Kickstarting the Integration 🌟

In the heart of our Basket.API project lies the StoreBasketHandler class. It's the maestro conducting the orchestra every time an item gracefully lands in the shopping cart.

Let the Discounts Flow 🌊

With every addition to the cart, the Basket Microservice will politely inquire with the Discount Grpc Service, “Any discounts for this gem?” And just like that, discounts are applied, bringing joy to both the cart and your wallet.

Behind the Scenes 🛠️

The Starting Point: Our adventure starts in StoreBasketHandler.cs. Here, we sprinkle some code magic to include discount calculations in the Handle method.

public async Task<StoreBasketResult> Handle(StoreBasketCommand command, CancellationToken cancellationToken)
{
// TODO : communicate with Discount.Grpc and calculate lastest prices of products into sc


// Store basket in database (use Marten upsert - if exist = update, if not exist = insert) and Update Cache
await repository.StoreBasket(command.Cart, cancellationToken);

return new StoreBasketResult(command.Cart.UserName);
}

Bridging Basket and Discount: We’ve equipped our Basket API with a shiny new gRPC client, ensuring smooth conversations with the Discount Grpc Service.

Discounts in Action: As we peruse through each cart item, we connect with the Discount Grpc Service, eagerly awaiting those sweet, sweet discounts. For every discount unveiled, we adjust the price tag on the cart item.

internal class StoreBasketCommandHandler(IBasketRepository repository, 
DiscountGrpcService discountGrpcService)
: ICommandHandler<StoreBasketCommand, StoreBasketResult>
{
public async Task<StoreBasketResult> Handle(StoreBasketCommand command, CancellationToken cancellationToken)
{
// Communicate with Discount.Grpc and calculate lastest prices of products into sc
foreach (var item in command.Cart.Items)
{
var coupon = await discountProto.GetDiscountAsync(new GetDiscountRequest { ProductName = item.ProductName }, cancellationToken: cancellationToken);
item.Price -= coupon.Amount;
}

// Store basket in database (use Marten upsert - if exist = update, if not exist = insert) and Update Cache
await repository.StoreBasket(command.Cart, cancellationToken);

return new StoreBasketResult(command.Cart.UserName);
}
}
  • For each cart item, call the Discount Grpc Service using the GetDiscountAsync method. Adjust the item’s price based on the discount amount received.

Neat and Tidy: To keep our code as organized as a Marie Kondo episode, we encapsulate the discount dance in a dedicated method, DeductDiscount. It's our little nook for all things discounts.

internal class StoreBasketCommandHandler(IBasketRepository repository, 
DiscountGrpcService discountGrpcService)
: ICommandHandler<StoreBasketCommand, StoreBasketResult>
{
public async Task<StoreBasketResult> Handle(StoreBasketCommand command, CancellationToken cancellationToken)
{
await DeductDiscount(command.Cart, cancellationToken);
await repository.StoreBasket(command.Cart, cancellationToken);

return new StoreBasketResult(command.Cart.UserName);
}

private async Task DeductDiscount(ShoppingCart cart, CancellationToken cancellationToken)
{
// Communicate with Discount.Grpc and calculate lastest prices of products into sc
foreach (var item in cart.Items)
{
var coupon = await discountProto.GetDiscountAsync(new GetDiscountRequest { ProductName = item.ProductName }, cancellationToken: cancellationToken);
item.Price -= coupon.Amount;
}
}
}

Dependency Injection Registration for gRPC Client: To awaken this magic, we ensure the Discount Grpc Service’s client gets the VIP treatment in our Basket API’s DI container. It’s like giving it a key to the city of services. Ensure that the grpc client (DiscountProtoService.DiscountProtoServiceClient) is registered within the ASP.NET Core Dependency Injection (DI) container.

//Grpc Services
builder.Services.AddGrpcClient<DiscountProtoService.DiscountProtoServiceClient>(options =>
{
options.Address = new Uri(builder.Configuration["GrpcSettings:DiscountUrl"]!);
});

Wrapping It Up with a Bow 🎁

And there you have it — a shopping experience that not only holds your items but also smartly applies discounts, making every addition to your cart a little celebration.

I have just published course — .NET 8 Microservices: C# 12, DDD, CQRS, Vertical/Clean Architecture.

This is step-by-step development of reference microservices architecture that include microservices on .NET platforms which used ASP.NET Web API, Docker, RabbitMQ, MassTransit, Grpc, Yarp API Gateway, PostgreSQL, Redis, SQLite, SqlServer, Marten, Entity Framework Core, CQRS, MediatR, DDD, Vertical and Clean Architecture implementation with using latest features of .NET 8 and C# 12.

--

--

Mehmet Ozkaya
Mehmet Ozkaya

Written by Mehmet Ozkaya

Software Architect | Udemy Instructor | AWS Community Builder | Cloud-Native and Serverless Event-driven Microservices https://github.com/mehmetozkaya

No responses yet