The coffeeshop apps on .NET Aspire
In Visual Studio
with the project opening, press F5
!!!
or
> dotnet build coffeeshop-aspire.sln
> dotnet run --project app-host/app-host.csproj
# http://localhost:5019
Notice: This is just a demo of how can we build and deploy the microservices approach. In the reality, the boundary should be defined by bounded-context concepts of Domain-driven Design, and totally based on the business domain, and might not be so fine-grained services like this demo, so you use it with care.
- Built on .NET 9.0 STS
- .NET Aspire 9
- Microservices architectural style
- Follows Vertical Sliding principles
- Domain Driven Design building blocks
- CQRS with MediatR and Fluent Validations
- Shift-left Observability with .NET Aspire (OpenTelemetry built-in)
- Custom OpenTelemetry for MediatR and FluentValidation handlers
- Custom OpenTelemetry for MassTransit on consumers
- Enrich .NET 8 global loggings
- OpenAPI supports
- Mapperly for generating object mappings
- API Versioning
- Integration test with .NET Aspire and Wiremock.NET
- Run it on GitHub Actions and output code coverage
- UUID v7
- Microsoft.Extensions.AI (Ollama for local dev and Azure OpenAI service)
- Response Caching - Distributed Caching with Redis
- JWT & Authentication with ASP.NET Identity
C4Context
title System Context diagram for CoffeeShop Application
Boundary(b0, "Boundary1") {
Person(customer, "Customers", "Customers of the coffeeshop.")
Boundary(b1, "Application", "boundary") {
System(SystemA, "CoffeeShop app", "Allows customers to submit and view their orders.")
}
Boundary(b2, "Infrastructure", "boundary") {
SystemDb(SystemD, "Database", "A system of the coffeeshop app.")
SystemQueue(SystemQ, "Message Queue", "A system of the coffeeshop app.")
}
}
Rel(customer, SystemA, "Uses")
Rel(SystemA, SystemD, "Uses")
Rel(SystemA, SystemQ, "Uses")
C4Container
title Container diagram for CoffeeShop Application
Person(customer, "Customers", "Customers of the coffeeshop.")
Container_Boundary(c1, "CoffeeShop Application") {
Container(reverse_proxy, "Gateway", "C#, .NET 8, YARP", "The reverse proxy/API gateway of the coffeeshop app.")
Container(counter_api, "Counter APIs", "C#, .NET 8, MassTransit", "The counter service.")
Container(barista_api, "Barista APIs", "C#, .NET 8, MassTransit", "The barista service.")
Container(kitchen_api, "Kitchen APIs", "C#, .NET 8, MassTransit", "The kitchen service.")
Container(order_summary, "Order Summary", "C#, .NET 8, Marten", "The order summary service.")
Container(product_api, "Product APIs", "C#, .NET 8", "The product service.")
Boundary(b1, "Docker containers", "boundary") {
ContainerDb(database, "Database", "Postgres", "Stores orders, audit logs, etc.")
ContainerQueue(message_broker, "Message Broker", "RabbitMQ", "Asynchronous communication between counter, barista, kitchen, and order-summary")
}
}
Rel(customer, reverse_proxy, "Uses", "HTTPS")
Rel(reverse_proxy, product_api, "Proxies", "HTTP")
Rel(reverse_proxy, counter_api, "Proxies", "HTTP")
Rel(order_summary, database, "Uses", "TCP")
Rel(counter_api, product_api, "Calls", "HTTP")
Rel(counter_api, message_broker, "Publishes", "TCP")
Rel(counter_api, message_broker, "Publishes", "TCP")
Rel_Back(barista_api, message_broker, "Subscribes", "TCP")
Rel_Back(kitchen_api, message_broker, "Subscribes", "TCP")
Rel_Back(order_summary, message_broker, "Subscribes", "TCP")
The detail blog of how to implement it at https://dev.to/thangchung/coffeeshop-app-infused-with-ai-intelligent-apps-development-202k