What is Service Discovery?

Service discovery is the mechanism that allows services to dynamically locate and communicate with each other at runtime. Rather than relying on fixed URLs or ports, services register themselves and are discoverable by name within the Aspire application model.

API

This supports the broader capability of dynamic connectivity, critical in modern distributed systems.

Service Discovery in Aspire

.NET Aspire abstracts away much of the complexity by allowing you to,

Let’s See Service Discover in Action

I am using the same aspire project that we have been building since the first chapter of this .NET Aspire Series. If you are new here, please check out the previous chapters.

  1. How to Get Started with .NET Aspire
  2. .NET Aspire: Setting Up Your Environment
  3. Core Concepts of .NET Aspire
  4. Enhancing Real-World Microservices with Resiliency in .NET Aspire
  5. Understanding Resiliency in .NET Aspire
  6. Service Orchestration in .NET Aspire
  7. Observability with the Aspire Dashboard

This is what my solution structure looks like,

Solution structure

Step 1. Open “Program.cs” from “BlazorWeatherApp.AppHost”.

This is how we have added all the Blazor UI/Microservices/Frontend projects into the App Host project with the Distributed Application instance.

 App Host project

Step 2. Adding/injecting Service endpoint’ dynamically.

We have made some changes here to add the dependency of the APIs/Services with other applications, where we need to call/use them.

Like I have “BlazorWeatherApp.WebApp” as a front end/UI for my end users, which needs the weather data from the weather API’s response.

To do this, I have passed the API project reference using the “WithReference()” method, and then I added, “WithExternalHttpEndpoints()”.

 API project

What it does- Let’s break down this code?

var builder = DistributedApplication.CreateBuilder(args);

var MyAPI = builder.AddProject<Projects.BlazorWeatherApp_API>("api");

var MyFrontEnd = builder.AddProject<Projects.BlazorWeatherApp_WebApp>("myweatherapp")
    .WithReference(MyAPI)
    .WithExternalHttpEndpoints();

Registers the BlazorWeatherApp_WebApp project (your frontend Blazor app) as "myweatherapp".

builder.Build().Run();

Step 3. Modify API Endpoints with API name.

As of now, we are calling API from https://localhost:7273/ in my Blazor Web App (Front End/UI). This is hardcoded in our Application Settings file, let’s modify this.

Blazor Web App

Note. This “API” is the same name that we used to register this API in the App Host project.

In earlier stages of development or without service discovery, it’s common to configure service URLs using fixed addresses like,

"BaseAddress": "https://localhost:7273/"

While this works for local development, it becomes a rigid and fragile approach when scaling to multiple environments (like staging, test, or production) or when services are deployed in containers.

Transition to Dynamic Service Discovery

To take advantage of .NET Aspire’s service discovery capabilities, we replace the hard-coded URL with a service-discoverable address:

"BaseAddress": "https+http://api/"

This change brings several benefits

Environment Agnostic

Dynamic Endpoint Resolution

Simplified Service-to-Service Communication

Before After
"BaseAddress": "https://localhost:7273/" "BaseAddress": "https+http://api/"
Hardcoded, environment-dependent Dynamic, environment-independent
Manual changes required Uses Aspire’s service discovery
Tightly coupled Loosely coupled, more scalable

Step 4. Let’s run App Host.

We are all set to test the new communication between our UI and Microservices/API Endpoints.

Now you can check the environment variables of the front end application in the dashboard which Aspire have added in your request.

Aspire

Console logs are also a best practice to test/review the requests generated by the Blazor Web App to API Endpoints.

Console logs

Why is Service Discovery helpful?