booking-microservices: A .NET 10 Architecture Reference
A practical microservices with the latest technologies and architectures like Vertical Slice Architecture, Event Sourcing, CQRS, DDD, gRpc, MongoDB, RabbitMq, Wolverine, and Aspire in .Net 10.
At a glance
- What is it?
- booking-microservices is a C# reference implementation for a booking domain using CQRS, DDD, event sourcing, RabbitMQ, gRPC, and .NET Aspire. It suits engineers studying service boundaries and distributed-system wiring, but it is not a documented, turnkey booking product.
- Who is it for?
- Adopt this repository as an architectural reference when your team has .NET, messaging, Kubernetes, and observability experience and can adapt its booking domain to real requirements. Do not adopt it as a ready-to-deploy booking product or as the sole production reference for its delivery guarantees.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why booking-microservices splits the booking domain
booking-microservices addresses the design and operational complexity of running a booking system as several cooperating services. Its purpose is architectural: the repository places domain logic, persistence, messaging, security, monitoring, and deployment patterns in one C# solution. The README says the project uses Domain Driven Design for business logic and identifies separate service boundaries within a booking domain. It is therefore most useful to .NET engineers studying how those boundaries are expressed in code and connected through contracts.
This is not a conventional booking application with a documented reservation journey, customer journey, or payment flow. The README concentrates on infrastructure and architecture choices rather than end-user booking rules. That distinction matters. A team looking for production-ready hotel or ticket inventory behavior still has to define domain entities, invariants, persistence mappings, APIs, and failure policies appropriate to its business. The repository can offer a technical assembly, but it cannot remove that product work.
The architecture also targets teams that already accept operational overhead. Postgres, MongoDB, RabbitMQ, IdentityServer, YARP, Kubernetes, ingress, TLS certificates, tracing, metrics, and logging all introduce components that must be configured and monitored. Aspire can coordinate services during local development, while the README also documents Docker Compose and Kubernetes paths. It does not present one universal production topology, so engineers should treat the deployment choices as explicit decisions rather than invisible defaults.
CQRS, event sourcing, and the booking write-read split
The repository separates command and query responsibilities. According to the README, CQRS is implemented with MediatR, Postgres serves the write side, and MongoDB serves the read side. A command travels through the application layer, where validation can run through FluentValidation and a validation pipeline behavior. The query path can then be modeled independently rather than reusing the aggregate persistence model as the API read model.
Event sourcing is applied specifically to the Booking Microservice or module. The README states that an event store records historical aggregate changes. That differs from using an event merely to notify another service after committing a normal database transaction. Event-sourced aggregates reconstruct state from stored events, so event compatibility, ordering, replay behavior, and schema evolution become part of application design. The README names EF Core, but it does not identify the concrete event-store implementation or show its persistence mappings.
Wolverine adds local queues and durable messaging patterns. The README describes local queues for internal commands and asynchronous in-process workflows, while RabbitMQ carries event-driven communication. A durable inbox is used by receivers for idempotency, and the README associates it with exactly once delivery semantics. A durable outbox is intended to prevent message loss with at least once delivery semantics. These are project design statements, not proof that every deployment has exactly once end-to-end processing. Engineers still need to inspect handlers, transaction boundaries, retry configuration, message identifiers, and failure recovery in the repository.
Service communication through Minimal API, gRPC, YARP, and Wolverine
Internal communication is divided by purpose. The README assigns gRPC to service-to-service calls, Minimal API to service endpoints, and YARP to the microservices gateway. CQRS requests inside an application are mediated through MediatR. Asynchronous integration is based on RabbitMQ and Wolverine rather than direct in-process coupling.
This design avoids forcing one transport across every interaction. Synchronous gRPC can provide a typed internal contract when one service needs a direct response. Minimal API gives the HTTP-facing boundary an ASP.NET Core entry point and supports generated OpenAPI documentation. YARP provides a gateway layer in front of services, while Nginx Ingress Controller handles load balancing at the Kubernetes ingress boundary. Those responsibilities are distinct, but they create more configuration surfaces and more places where authentication, routing, versioning, and observability must be aligned.
Wolverine occupies both the in-process and external messaging roles described by the README. Its local queues support internal commands and workflows, while its RabbitMQ transport supports distributed messaging. This reduces direct calls between workflow steps, but it changes failure handling. A handler may execute after a request has returned, an unexpected message may be retried, and a downstream service may be temporarily unavailable. The README also lists PactNet contract testing, which is relevant to producer and consumer compatibility. It does not show which contracts are currently enforced or how consumers behave when an event changes.
Aspire, Docker Compose, and Kubernetes execution paths
The repository presents Aspire as the local orchestration layer for service discovery, observability, and application startup. Based on the repository layout, Aspire configuration lives under `.aspire/`, while deployment material is kept separately under `deployments/`. This separation indicates that local composition and production deployment are related but distinct concerns.
Docker Compose and Kubernetes are both documented as execution mechanisms. The Kubernetes path adds YARP, Nginx Ingress Controller, cert-manager for TLS configuration, and infrastructure intended for scaling and high availability. MongoDB, RabbitMQ, Postgres, and the observability components must also be represented appropriately in whichever environment is selected. The README does not state that every component runs in every profile, so the actual files under `deployments/` and `.aspire/` should be checked before selecting a startup path.
Observability is broad for a reference repository. Serilog feeds Kibana for logging. OpenTelemetry integrates with Jaeger for distributed tracing and with Prometheus and Grafana for monitoring. ASP.NET Core health checks report infrastructure status. These features can help engineers see request flow, service state, and telemetry failure during distributed development, but they also add storage, configuration, dashboard, and retention work. A functioning dashboard is not an actionable alerting policy, and the README does not document alert definitions or production retention.
Preparing tools and completing the first formatting check
dotnet tool restoreThe package.json check-only script then verifies formatting without applying changes. A successful invocation means the configured formatter accepted the solution's current formatting. It does not verify MongoDB, RabbitMQ, Postgres, IdentityServer, certificates, Kubernetes, or Aspire orchestration. Invoke it through the documented package script:
npm run ci-formatThe repository provides NSubstitute-based unit tests and Testcontainers-based integration and end-to-end tests. PactNet covers contract testing. Those test categories indicate deliberate coverage across small units, real dependencies, and service contracts, but the README does not state test counts, coverage percentages, or required container startup order.
Where booking-microservices is the wrong architectural fit
The largest limitation is the gap between a reference architecture and a complete booking product. The README names technologies and architectural patterns, but it does not define a production reservation workflow, payment integration, cancellation policy, inventory rule, or tenant model. Code that demonstrates how a command and event are wired is not the same as code that satisfies booking-specific business requirements.
The infrastructure requirements are another constraint. Running the complete topology means dealing with multiple data stores, a broker, identity infrastructure, certificates, and observability services. During development, Aspire can coordinate parts of the environment. During deployment, Kubernetes introduces its own manifests, ingress, secrets, and availability assumptions. A small team may spend more time adapting infrastructure than implementing its product domain.
The delivery guarantees require equally careful interpretation. Wolverine's inbox and outbox patterns are useful mechanisms, but exactly once and at least once are claims that depend on transaction design, message persistence, handler behavior, and failure recovery. The README does not document operational procedures for replaying events, repairing poison messages, migrating read models, or coordinating schema changes. Those gaps make the repository a starting point for engineering investigation rather than proof that distributed delivery is already production-ready.
The licensing picture is simple but limited. The repository uses the MIT license, which permits reuse and modification under its terms. This review does not interpret dependency licenses or provide legal advice. A team adopting the code must still review the licenses of RabbitMQ, MongoDB, Postgres, IdentityServer, Wolverine, MediatR, and the other packages used in its deployment.
booking-microservices versus the monolith repositories
The README links to companion repositories named Booking with Modular Monolith Architecture and Booking with Monolith Architecture. Their names establish the real architectural difference: this repository distributes the booking system across services and adds network, messaging, deployment, and consistency concerns.
The comparison is not merely microservices versus no microservices. This implementation uses separate read and write stores, an event store, gRPC, RabbitMQ, a gateway, and Kubernetes deployment assets. A monolith may still use CQRS or domain-oriented modules, but selecting it changes the operational topology and the number of process and network boundaries. The README does not provide a feature-by-feature comparison or benchmark, so no claim about speed, reliability, or development cost should be inferred from the architecture label alone.
A small team or an early product that cannot operate multiple services and supporting infrastructure may find the monolith repositories easier starting points. A team that needs independently deployed domain capabilities and wants to study explicit service contracts can use booking-microservices as a reference. The decision should follow actual deployment and ownership requirements, not the number of technologies included in the solution.
The repository is not archived, and its last push was on 2026-10-06. Recent release history includes `v2.3.0` on 2026-10-06, `v2.2.0` on 2025-07-23, and `v2.1.0` on 2025-04-18. That history confirms recent repository activity, but it does not establish production stability, upgrade compatibility, or the cost of adopting the architecture.
Editorial conclusion
Adopt this repository as an architectural reference when your team has .NET, messaging, Kubernetes, and observability experience and can adapt its booking domain to real requirements. Do not adopt it as a ready-to-deploy booking product or as the sole production reference for its delivery guarantees. Before starting, inspect the domain boundaries, required infrastructure, event schemas, authentication setup, database migrations, and deployment assumptions in each bounded context.
Frequently asked questions
What architecture patterns does booking-microservices demonstrate?
The README lists Vertical Slice Architecture, DDD, CQRS, Event Sourcing, event-driven architecture, and clean architecture. It also uses MediatR for CQRS, Wolverine for durable messaging, and an event store for historical Booking aggregate changes.
How does booking-microservices handle messaging and delivery?
RabbitMQ is used with Wolverine for event-driven messaging. The README describes a durable inbox for receiver idempotency and exactly once delivery, plus a durable outbox to prevent message loss with at least once delivery.
What databases and communication technologies does booking-microservices use?
The README assigns Postgres to the write side and MongoDB to the read side. Internal synchronous communication uses gRPC, public endpoints use Minimal API, and YARP provides the gateway layer.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/meysamhadeli-booking-microservices)Was this useful?