Distributed Caching with Redis in Basket Microservices using .NET 8
In this article, we will continue our EShop Microservices and this will be Distributed Caching with Redis in Basket Microservices using .NET 8.
I have just published course — .NET 8 Microservices: C# 12, DDD, CQRS, Vertical/Clean Architecture.
Domain Models of Basket Microservices 🧐
At the heart of our Basket Microservices lies the ‘Shopping Cart’ model, intricately linked with ‘Shopping Cart Item’. A Shopping Cart in our domain is not just an item but an entity with attributes that define its essence — UserName, Items and TotalPrice.
This detailed representation not only gives us clarity on the structure of our data but also prepares us for the potential domain events that might arise, such as basket checkout event, which could lead to broader integration events.
REST API Endpoints of Basket Microservices 🌐
Our service’s accessibility hinges on a set of well-defined RESTful APIs. These endpoints are the conduits through which our users interact with the Basket:
Each endpoint is meticulously crafted, adhering to ASP.NET Core controller conventions, ensuring clarity and consistency across our service.
Underlying Data Structures 🛠️
Basket Microservices has 2 Datastore:
- Marten Document Database
- Redis Distributed Cache
Marten is a powerful library that transforms PostgreSQL into a .NET Transactional Document DB using PostgreSQL’s JSON column features. Redis a powerful in-memory data store and distributed cache which is good fit for microservices arcihtectures.
The Game Plan 📋
We integrate Redis into our Basket Microservices to cache user shoppingcart data. This enhances performance by reducing the load on our database and speeding up data retrieval.
Redis: The Speedster of Caching 🏎️💨
Redis a powerful in-memory data store and distributed cache which is good fit for microservices architectures. Redis is an advanced key-value store known for its high performance. It is often used for caching, session storage, pub/sub systems, and more. Redis offers in-memory data storage, resulting in fast data access. Its support for various data structures makes it versatile for different use cases.
Why Choose Redis for Distributed Caching 🧩
Redis is an excellent choice for microservices architecture primarily due to its inherent distributed characteristics and performance efficiencies. Microservices often need to share state or data in a distributed environment. Redis as a distributed cache, enabling services to access shared data quickly and reducing the load on databases.
Redis is like the communal fridge 🍽️ where all our microservices can store and share their snacks (data, I mean). It’s all about quick access to shared data, making everyone happy and well-fed (data-wise, again).
Putting the Pieces Together 🛠️
Here’s the action plan:
- Proxy & Decorator Patterns: We’re getting fancy with our code organization, making it cleaner and more maintainable.
- Cache-Aside Pattern: No stale data here! We’re keeping things fresh and up-to-date.
- Scrutor Magic: This library is like our coding wand 🪄, making it easy to sprinkle some decorator pattern goodness in our app.
- Redis Setup with Docker-Compose: We’re giving Redis its cozy container home 🏠 in our Docker environment, making sure it’s all set to work with our microservices.
- Integration Time: We’re hooking up Redis with our Basket Microservices to cache user cart data, making data access lightning-fast.
🎭 The Setup: Proxy and Decorator in Play
Let’s get our Basket Microservices zooming with some clever caching strategies using the Proxy and Decorator patterns. We’re crafting a CachedBasketRepository
that's going to make data retrieval as quick as a flash!
We’re setting the stage with CachedBasketRepository
, a nifty class that's going to layer in some caching goodness on top of our regular IBasketRepository
. It's like giving our repository a super-speedy sidekick!
🛠️ Creating the CachedBasketRepository
Here’s the blueprint:
- Laying the Foundations: Our
CachedBasketRepository
is going to implement the sameIBasketRepository
interface. It's like it's wearing the same team jersey, playing for team BasketRepository! - Befriending the Base Repository: Inside, it’s wrapping around an instance of
BasketRepository
. Think of it as having a best buddy it can rely on for the heavy lifting. - Stepping Up the Game: Now, for each method —
GetBasket
,StoreBasket
, andDeleteBasket
- it's doing a bit of magic 🪄. Before it just passes the call to its buddy, it checks if it can handle things faster with caching.
📝 The Code Magic
We’ll focus on implementing CachedBasketRepository in the Basket Microservices, which utilizes the Proxy and Decorator patterns. This class acts as a decorator over IBasketRepository, adding caching functionality to optimize data retrieval and manipulation.
public class CachedBasketRepository(IBasketRepository repository) : IBasketRepository
{
public async Task<ShoppingCart> GetBasket(string userName, CancellationToken cancellationToken = default)
{
return await repository.GetBasket(userName, cancellationToken);
}
public async Task<ShoppingCart> StoreBasket(ShoppingCart basket, CancellationToken cancellationToken = default)
{
return await repository.StoreBasket(basket, cancellationToken);
}
public async Task<bool> DeleteBasket(string userName, CancellationToken cancellationToken = default)
{
return await repository.DeleteBasket(userName, cancellationToken);
}
}
🎨 Decorator Pattern at Work
Our CachedBasketRepository
is a textbook Decorator pattern example. It's taking the plain old repository and jazzing it up with caching, without changing its core duties.
Proxy Pattern: CachedBasketRepository acts as a proxy, forwarding calls to the underlying BasketRepository instance.
Decorator Pattern: It extends the functionality of BasketRepository by adding caching logic.
🚀 Ready for Lift-Off!
With our CachedBasketRepository
all set up, we're on the brink of giving our Basket Microservices a major speed boost. Stay tuned as we integrate Redis and watch our microservices fly!
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.