eShop, mapped from the code.
Microsoft's .NET Aspire reference app: ASP.NET Core APIs, a gRPC basket, Blazor web apps and MAUI clients over REST, gRPC and a RabbitMQ event bus. Kuuhaku read its source at commit dc7ea49, with no configuration and no hand-fixing, and found 19 services in C# and 31 connections: 20 over HTTP, 9 through queues, 1 through a shared database and 1 over gRPC. Each one below says how it was found.
Services
Every repo or deployable the scanner found, with how many connections leave it and reach it.
| Service | Stack | Role | Calls | Called by |
|---|---|---|---|---|
ordering_api | C# · ASP.NET Core | service | 7 | 6 |
eventbus | C# · .NET | service | 0 | 8 |
catalog_api | C# · ASP.NET Core | service | 3 | 3 |
identity_api | C# · ASP.NET Core | service | 0 | 6 |
webapp | C# · ASP.NET Core | consumer | 5 | 1 |
basket_api | C# · ASP.NET Core | service | 2 | 3 |
webhooks_api | C# · ASP.NET Core | service | 2 | 3 |
eshop_apphost | C# · .NET | consumer | 4 | 0 |
orderprocessor | C# · .NET | service | 3 | 0 |
paymentprocessor | C# · ASP.NET Core | service | 2 | 1 |
webhookclient | C# · ASP.NET Core | service | 2 | 0 |
clientapp | C# · .NET | consumer | 1 | 0 |
eshop_servicedefaults | C# · .NET | service | 0 | 0 |
eventbusrabbitmq | C# · .NET | service | 0 | 0 |
hybridapp | C# · .NET | consumer | 0 | 0 |
integrationeventlogef | C# · .NET | service | 0 | 0 |
ordering_domain | C# · .NET | service | 0 | 0 |
ordering_infrastructure | C# · .NET | service | 0 | 0 |
webappcomponents | C# · .NET | consumer | 0 | 0 |
Connections
config: the address is written in configuration (an env file, a compose file, a proxy route) and the call is matched to it. inferred: the call's path matches a route of the target and nothing contradicts it. Call sites count the places in the code that make the call.
| From | To | Type | Evidence | Call sites | How it was found |
|---|---|---|---|---|---|
basket_api | eventbus | HTTP | inferred | 1 | "eventbus" in Extensions/Extensions.cs:18 |
basket_api | identity_api | HTTP | config | — | WithReference identity-api in AppHost.cs |
catalog_api | eventbus | HTTP | inferred | 1 | "eventbus" in Extensions/Extensions.cs:31 |
catalog_api | ordering_api | queue | inferred | 2 | new OrderStockConfirmedIntegrationEvent(…) in catalog_api IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs:29, consumed in ordering_api Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs:6; new OrderStockRejectedIntegrationEvent(…) in catalog_api IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs:28, consumed in ordering_api Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs:4; new OrderStockConfirmedIntegrationEvent(…) in catalog_api IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs:29, consumed in ordering_api Extensions/Extensions.cs:56; new OrderStockRejectedIntegrationEvent(…) in catalog_api IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs:28, consumed in ordering_api Extensions/Extensions.cs:57 |
catalog_api | webhooks_api | queue | inferred | 1 | new ProductPriceChangedIntegrationEvent(…) in catalog_api Apis/CatalogApi.cs:395, consumed in webhooks_api Extensions/Extensions.cs:21; new ProductPriceChangedIntegrationEvent(…) in catalog_api Apis/CatalogApi.cs:395, consumed in webhooks_api IntegrationEvents/ProductPriceChangedIntegrationEventHandler.cs:3 |
clientapp | basket_api | gRPC | inferred | 1 | Basket client in Services/Basket/BasketService.cs, served in basket_api/Grpc/BasketService.cs |
eshop_apphost | catalog_api | HTTP | config | 11 | URL worked out at AppHost.cs:64, sent by ConfigureMobileBffRoutes in Extensions.cs:97 |
eshop_apphost | eventbus | HTTP | inferred | 1 | "eventbus" in AppHost.cs:10 |
eshop_apphost | identity_api | HTTP | config | — | YARP mobile-bff routes to identity-api in AppHost.cs |
eshop_apphost | ordering_api | HTTP | config | — | YARP mobile-bff routes to ordering-api in AppHost.cs |
ordering_api | basket_api | queue | inferred | 1 | new OrderStartedIntegrationEvent(…) in ordering_api Application/Commands/CreateOrderCommandHandler.cs:32, consumed in basket_api Extensions/Extensions.cs:19; new OrderStartedIntegrationEvent(…) in ordering_api Application/Commands/CreateOrderCommandHandler.cs:32, consumed in basket_api IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs:8 |
ordering_api | catalog_api | queue | inferred | 2 | new OrderStatusChangedToAwaitingValidationIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs:33, consumed in catalog_api Extensions/Extensions.cs:32; new OrderStatusChangedToPaidIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs:32, consumed in catalog_api Extensions/Extensions.cs:33; new OrderStatusChangedToAwaitingValidationIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs:33, consumed in catalog_api IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs:7; new OrderStatusChangedToPaidIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs:32, consumed in catalog_api IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs:6 |
ordering_api | eventbus | HTTP | inferred | 1 | "eventbus" in Extensions/Extensions.cs:28 |
ordering_api | identity_api | HTTP | config | — | WithReference identity-api in AppHost.cs |
ordering_api | paymentprocessor | queue | inferred | 1 | new OrderStatusChangedToStockConfirmedIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs:30, consumed in paymentprocessor IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs:7; new OrderStatusChangedToStockConfirmedIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs:30, consumed in paymentprocessor Program.cs:6 |
ordering_api | webapp | queue | inferred | 5 | new OrderStatusChangedToAwaitingValidationIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs:33, consumed in webapp Extensions/Extensions.cs:45; new OrderStatusChangedToPaidIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs:32, consumed in webapp Extensions/Extensions.cs:46; new OrderStatusChangedToStockConfirmedIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs:30, consumed in webapp Extensions/Extensions.cs:47; new OrderStatusChangedToShippedIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs:30, consumed in webapp Extensions/Extensions.cs:48 |
ordering_api | webhooks_api | queue | inferred | 2 | new OrderStatusChangedToShippedIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs:30, consumed in webhooks_api Extensions/Extensions.cs:22; new OrderStatusChangedToPaidIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs:32, consumed in webhooks_api Extensions/Extensions.cs:23; new OrderStatusChangedToPaidIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs:32, consumed in webhooks_api IntegrationEvents/OrderStatusChangedToPaidIntegrationEventHandler.cs:6; new OrderStatusChangedToShippedIntegrationEvent(…) in ordering_api Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs:30, consumed in webhooks_api IntegrationEvents/OrderStatusChangedToShippedIntegrationEventHandler.cs:6 |
orderprocessor | eventbus | HTTP | inferred | 1 | "eventbus" in Extensions/Extensions.cs:10 |
orderprocessor | ordering_api | shared database | config | — | WithReference(orderDb) in orderprocessor and WithReference(orderDb) in ordering_api name the same database aspire orderingdb |
orderprocessor | ordering_api | queue | inferred | 1 | new GracePeriodConfirmedIntegrationEvent(…) in orderprocessor Services/GracePeriodManagerService.cs:56, consumed in ordering_api Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs:5; new GracePeriodConfirmedIntegrationEvent(…) in orderprocessor Services/GracePeriodManagerService.cs:56, consumed in ordering_api Extensions/Extensions.cs:55 |
paymentprocessor | eventbus | HTTP | inferred | 1 | "EventBus" in Program.cs:5 |
paymentprocessor | ordering_api | queue | inferred | 2 | new OrderPaymentFailedIntegrationEvent(…) in paymentprocessor IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs:27, consumed in ordering_api Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs:6; new OrderPaymentSucceededIntegrationEvent(…) in paymentprocessor IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs:23, consumed in ordering_api Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs:6; new OrderPaymentFailedIntegrationEvent(…) in paymentprocessor IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs:27, consumed in ordering_api Extensions/Extensions.cs:58; new OrderPaymentSucceededIntegrationEvent(…) in paymentprocessor IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs:23, consumed in ordering_api Extensions/Extensions.cs:59 |
webapp | basket_api | HTTP | config | 1 | http://basket-api in Extensions/Extensions.cs; WithReference basket-api in AppHost.cs |
webapp | catalog_api | HTTP | config | 8 | URL worked out at Program.cs:32 |
webapp | eventbus | HTTP | inferred | 1 | "EventBus" in Extensions/Extensions.cs:17 |
webapp | identity_api | HTTP | config | — | WithReference identity-api in AppHost.cs |
webapp | ordering_api | HTTP | config | 2 | URL worked out at Services/OrderingService.cs:9 |
webhookclient | identity_api | HTTP | config | — | WithReference identity-api in AppHost.cs |
webhookclient | webhooks_api | HTTP | config | 2 | URL worked out at Services/WebHooksClient.cs:7 |
webhooks_api | eventbus | HTTP | inferred | 1 | "eventbus" in Extensions/Extensions.cs:7 |
webhooks_api | identity_api | HTTP | config | — | WithReference identity-api in AppHost.cs |
Left for a person
4 items the scanner would not settle on its own and put in the review inbox instead of guessing:
httpinclientapp: base URL assigned at runtime (Services/RequestProvider/RequestProvider.cs:24)httpinhybridapp: base URL assigned at runtime (Services/CatalogService.cs:16)httpinwebappcomponents: base URL assigned at runtime (Services/CatalogService.cs:14)httpinwebhooks_api: base URL assigned at runtime (Services/GrantUrlTesterService.cs:14)
Other systems
- OpenTelemetry Demo: 23 services, 30 connections
- Train Ticket: 48 services, 140 connections
- Online Boutique: 12 services, 16 connections
- Robot Shop: 9 services, 12 connections
- Sock Shop: 8 services, 7 connections
- Bank of Anthos: 8 services, 9 connections
- Quarkus Super Heroes: 7 services, 6 connections
- Spring PetClinic Microservices: 7 services, 14 connections
Your own system
Run npx kuuhaku scan . in a folder of repos: it reads the code on your machine and only the graph leaves it. Or connect GitHub or Bitbucket and let the hosted runner scan with a read-only key. The map, a page per repo, a review inbox and a check on every pull request follow. Start free.