Owlet — .NET Microservices Platform
The order exists because a message was delivered
Overview
Four .NET services behind a gateway, with a durable queue between them
Two services have to agree about an order and one of them is down. What happens to the order?
Four ASP.NET Core services sit behind an nginx gateway. A JWT issued by one of them is validated independently by the others, so no request has to phone home to the identity service. The basket is held in Redis, orders and catalogue in SQL Server, and an order event is published to RabbitMQ by one service and consumed by another. The admin view of an order exists only because a message was delivered.

Evidence
What it looks like running
One unbroken take: sign in, add two items, work through the checkout wizard, place the order, and open the admin Order events page where the row is already waiting Every row exists because API.Basket published an OrderPlaced message and API.Admin consumed it off the durable queue owlet-order-placed — published and consumed timestamps, time on the bus, and the event id The broker view while API.Admin is stopped: the durable queue owlet-order-placed holds one ready, persistent message with zero consumers attached Serilog output from all four services in one Seq instance, filtered to the consumed OrderPlaced events — the expanded row carries the event id, the order id and the Service and SourceContext that emitted it The Angular 20 storefront behind the nginx gateway: the catalogue paged from API.Basket, with its pictures served from API.Web's wwwroot on the same origin The review step is explicit about the deployment: with no Stripe secret key the order is still written, priced from the database and published to the queue, and its status stays Pending
Engineering
How it was built
Frontend
- Angular storefront and admin views
Backend & services
- Four ASP.NET Core services behind an nginx gateway
- JWT issued by the identity service and validated independently by the others
- Redis-backed basket, two SQL Server databases
- Checkout re-reads the price from the database rather than trusting the basket
Integrations
- Order event published to RabbitMQ by one service and consumed by another
- Queue holds messages while the consumer is stopped and drains on restart
- Order event crosses the bus in 5–9 ms on a warm stack
- Serilog structured logging from every hop into Seq
Testing & verification
- 105 tests
CI/CD & workflow
- Whole stack reproducible with one docker compose up
Applied
Skills on this project
Next step
Ready to bring your project to life?
Schedule a free 30-minute strategy call with our team.
No sales call. You will talk to the engineer who would do the work, and you will get a written summary either way.