Skip to content
All projects

BACKEND / MICROSERVICES

.NET Microservices Ordering Platform

Seven ASP.NET Core services behind an Ocelot API gateway, each with its own SQL Server database. Services communicate asynchronously through Azure Service Bus queues and topics. This system later became the target for my MSc security work.

  • 7 services
  • 19 gateway routes
  • Azure Service Bus topics
Context
Backend project
Period
2024 – 2025

Stack

  • .NET 8
  • ASP.NET Core
  • Entity Framework Core
  • SQL Server
  • Azure Service Bus
  • Ocelot
  • JWT
  • Stripe
  • Swagger
  • Bootstrap 5

Project overview

An ordering platform split along business boundaries: Auth, Product, Coupon, ShoppingCart, Order, Reward and Email. An ASP.NET Core MVC front-end talks only to the gateway. Each service owns its data and publishes events instead of calling other services directly for side effects.

Architecture

Synchronous calls go through the gateway; side effects go through the message bus.
Messaging contracts
ChannelTypeProducer → consumer
OrderCreatedTopicOrder → Reward and Email (one subscription each)
emailshoppingcartQueueShoppingCart → Email
registeruserQueueAuth → Email

Engineering decisions

A topic for OrderCreated
Rewards and email react to the same event independently. Adding a new reaction means adding a subscription; the Order service doesn't change.
Database per service
No service reads another service's tables, so schemas can change independently. EF Core migrations live with each service.
Gateway as the only entry point
The front-end knows one address. Routing and authentication at the edge are configured in one file (ocelot.json).
Shared message bus library
Mango.MessageBus wraps publishing, so services depend on a small interface instead of the Azure SDK directly.

Implementation

  • N-layer services using the repository and unit-of-work patterns, each with its own Swagger/OpenAPI document.
  • Authentication with ASP.NET Core Identity issuing JWTs with roles, validated by every service.
  • Stripe Checkout sessions for payment, with coupons synchronised to Stripe.
  • Background consumers (AzureServiceBusConsumer) in the Email and Reward services process messages outside the request path.

What I learned

  • Asynchronous messaging removes coupling, but you need idempotent consumers because messages can arrive more than once.
  • Microservices move complexity from code into operations and security, which is what my MSc thesis then measured on this same system.

Source