Posts

Apache Kafka Implementation in .NET – A Practical Microservices Guide

Modern enterprise applications demand high throughput, fault tolerance, and real-time data processing . Traditional synchronous APIs struggle at scale. This is where Apache Kafka becomes a backbone for event-driven microservices. In this article, we will explore Kafka implementation using .NET with real-world architecture, producer & consumer examples, and best practices. Why Kafka for Microservices? High-throughput event streaming Loose coupling between services Fault tolerance and durability Replayable event history Horizontal scalability Kafka Architecture – Core Concepts Kafka Components Producer – Publishes events Topic – Logical event stream Partition – Parallelism unit Broker – Kafka server Consumer Group – Scalable consumers Offset – Message position Kafka Microservices Architecture +-------------------+ | Web / API Layer | +-------------------+ | v +-------------------+ | Kafka Produce...

Azure Service Bus vs Apache Kafka in .NET Microservices

A Practical Comparison Guide

When I started building .NET microservices , everything looked clean on architecture diagrams. But as traffic increased, synchronous HTTP calls quickly became a bottleneck. That’s when asynchronous messaging in .NET microservices became unavoidable. The real question then was: Azure Service Bus vs Apache Kafka in .NET microservices , which messaging system is the right choice for scalability, performance, and real-world production workloads? Why Messaging Is Critical in Microservices Loose coupling between services Fault isolation Independent scalability Event-driven workflows Two technologies dominate in .NET microservices: Azure Service Bus and Apache Kafka . Azure Service Bus – Enterprise Messaging Azure Service Bus is ideal for business workflows where reliability, ordering, and security are non-negotiable. Azure Service Bus Architecture font-size="14" x="70" y="115">Order Service font-size="1...

How I Built a JWT Refresh Token Middleware in ASP.NET Core

A few months ago, I was working on a project where our APIs were protected using JWT tokens . Everything was running smoothly… until we realized that our tokens were expiring too quickly . Users were getting logged out, and every client request needed re-authentication. That’s when I decided to implement a refresh token mechanism directly in middleware, and it turned out to be a neat solution. Understanding the Problem JWT tokens are stateless and self-contained , which is great for scalability, but the downside is that once they expire, the user needs a new token. Traditionally, developers handle this on the client side with a separate refresh endpoint. But I wanted a more transparent approach : Whenever a valid token was nearing expiration, the server would automatically issue a new token. This would reduce friction for the user. The new token would be added to the response headers so clients could pick it up without changing the response payload. Step 1: Creating Midd...

How I Learned to Secure My APIs with RS256 JWT Tokens in C#

A few weeks ago, I was working on a project where we needed secure API authentication . We were using JWT (JSON Web Tokens), and I realized that using RS256 for signing tokens was the best approach. Unlike HS256, which uses a shared secret, RS256 uses asymmetric keys — one private key for signing and a public key for verification. This was perfect for our microservices architecture. Step 1: Generating an RSA Key Pair First, we need an RSA key pair: using var rsa = RSA.Create(2048); var privateKey = rsa.ExportRSAPrivateKey(); // Keep secret var publicKey = rsa.ExportRSAPublicKey(); // Can share I learned that storing keys securely is critical. For production, I’d use something like Azure Key Vault or AWS KMS instead of local files. Step 2: Generating the JWT Token Next, I used the private key to sign my token: var rsa = RSA.Create(); rsa.ImportRSAPrivateKey(Convert.FromBase64String("YOUR_PRIVATE_KEY_BASE64"), out _); var signingCredentials = new Si...

When a Race Condition Caught Me Off Guard: A Real-Life Developer Story

Race conditions are tricky beasts, especially in high-transaction systems. I encountered one recently while working on a system handling user transactions, and it led to inconsistencies, failed reports, and a lot of debugging. Here’s my journey—what went wrong, what I tried, and how we finally solved it. The Situation We had two tables: Transactions - stores individual user transactions. Reports - aggregates transaction data for reporting. Multiple processes were updating these tables concurrently. Sometimes the balance was deducted but reports weren’t updated , and sometimes the order was reversed, causing mismatched data. Classic race condition. --- Initial Approach: Entity Framework Updates Initially, we were using Entity Framework to read, modify, and save balances: // EF Core update var balance = _context.Accounts.Find(accountId); balance.Amount -= transactionAmount; await _context.SaveChangesAsync(); This worked in development, but under high concurrency, ...

Api Versioning in .Net Core

Mastering API Versioning and Dynamic Swagger Implementation in .NET Core As applications grow, APIs evolve frequently. Maintaining backward compatibility while introducing new features can be challenging. API versioning ensures old clients continue working, while Swagger (OpenAPI) provides interactive documentation for developers. In this post, we’ll dive deeper into dynamically generating Swagger JSON for multiple API versions in .NET Core. Why Dynamic Swagger JSON? When you have multiple API versions, it’s tedious to manually maintain separate Swagger documents for each version. Dynamic generation allows your Swagger UI to automatically pick up new versions as they are added to controllers, without extra configuration. --- Setting Up API Versioning // Program.cs builder.Services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.ReportApiVersions = true; }); builder.Se...

How I Solved a Real Entity Framework Deadlock Caused by Different Table Order in High-Transaction Systems

The Day a Deadlock Brought Down My High-Transaction System: My Real Experience with Entity Framework Every developer has one story that sticks with them forever. For me, it was the night my high-transaction system started throwing Entity Framework deadlock errors faster than I could refresh my logs. Everything was running perfectly earlier that day. But by evening, users started reporting issues, transactions were halting, and logs began filling with the dreaded message: “Transaction (Process ID xx) was deadlocked on lock resources…” I knew this wasn’t going to be a normal night. 🔍 It All Started With a Simple Deadlock Error It was late when I saw the first error. In one part of the system, customers were generating PINs. The balance was deducted successfully — but the transaction report wasn’t updating. Instead, the application threw a deadlock exception. Minutes later, more deadlocks appeared. Something was wrong. 🧩 Debugging the Issue: The Unexpected Discovery I be...