BFF Web
view on github →Single gateway from the browser to every microservice. Rate-limit, circuit-break, idempotency-replay, and the chaos fault-injection handler all live here.
.NET 9 + Aspire orchestration, MassTransit event mesh, Postgres + Redis + RabbitMQ + Vault. Real production patterns, not slideware. The static reference is below; the live cluster under fault injection is on /chaos.
Every browser request lands on the BFF. The BFF fans out over HTTP to the five microservices, which own their own Postgres schemas. Cross-service coordination flows through RabbitMQ via MassTransit. Catalog reads go through Redis as an L2 cache. Identity and the BFF lease dynamic credentials from Vault.
Each service has a single responsibility, its own Postgres schema, and the patterns that responsibility forces. Stack, patterns, and a click-driven demo for the headline pattern.
Single gateway from the browser to every microservice. Rate-limit, circuit-break, idempotency-replay, and the chaos fault-injection handler all live here.
JWT issuance, refresh, JTI revocation, and dynamic Postgres credentials sourced from Vault.
Products, stock, OCC. Two replicas via Aspire WithReplicas. The hot path for every browse, every checkout.
Idempotent claim creation. Owns the public idempotency contract for the storefront.
Stripe + PayPal webhook processors. Transactional outbox for outbound MassTransit events.
The saga state machine. Coordinates StockReservation → PaymentSession → Capture → Complete, with a compensation arc on every step.
MassTransit state machine. Each event is published, each consumer transitions state, each failure has a named compensating event. No 2PC. No distributed locks. Run a real saga with a forced failure on /chaos to see compensation fire end-to-end.
Click "Run race" to fire N concurrent inventory updates carrying the same xmin. Postgres lets exactly one win; the rest fail with 412 Precondition Failed. No lost updates.
Why every cross-service flow uses a MassTransit saga instead of a distributed transaction, and what compensation means in practice.
Reliable event publishing without 2PC. Outbox table + dispatcher worker + idempotent consumers.
How dynamic Postgres credentials rotate hourly without dropping in-flight queries.