What is the AppHost?
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
Aspire’s AppHost is the code-first place where you declare your application’s services and their relationships. Instead of managing scattered configuration files, you describe the architecture in code. Aspire then handles local orchestration so you can focus on building features.
Defining your architecture
Section titled “Defining your architecture”Consider a simple three-tier architecture where a frontend talks to an API, and the API relies on a database. Select an API language below to see the examples demonstrated in that language.
architecture-beta service db(logos:postgresql)[PostgreSQL] service api(logos:dotnet)[API service] service frontend(logos:react)[React frontend] api:R --> L:db frontend:R --> L:api
This architecture demonstrates a .NET API connecting to a PostgreSQL database, with a React frontend consuming the API. The .NET API uses ASP.NET Core and connects to PostgreSQL using Entity Framework or a connection string. The React frontend is built with Vite and communicates with the API over HTTP.
To build this architecture step-by-step, see the Build your first app quickstart.
architecture-beta service db(logos:postgresql)[PostgreSQL] service api(logos:python)[API service] service frontend(logos:react)[React frontend] api:R --> L:db frontend:R --> L:api
This architecture demonstrates a Python API (using FastAPI/Uvicorn) connecting to a PostgreSQL database, with a React frontend consuming the API. The Python API uses frameworks like FastAPI or Flask and connects to PostgreSQL using libraries like psycopg2 or SQLAlchemy. The React frontend is built with Vite and communicates with the API over HTTP.
To add this architecture to an existing Python-backed app, start with Add Aspire to an existing app and then review the Python integration.
architecture-beta service db(logos:postgresql)[PostgreSQL] service api(logos:nodejs-icon)[API service] service frontend(logos:react)[React frontend] api:R --> L:db frontend:R --> L:api
This architecture demonstrates a Node.js API connecting to a PostgreSQL database, with a React frontend consuming the API. The Node.js API uses frameworks like Express or Fastify and connects to PostgreSQL using libraries like pg or Prisma. The React frontend is built with Vite and communicates with the API over HTTP.
architecture-beta service db(logos:postgresql)[PostgreSQL] service api(logos:go)[API service] service frontend(logos:react)[React frontend] api:R --> L:db frontend:R --> L:api
This architecture demonstrates a Go API connecting to a PostgreSQL database, with a React frontend consuming the API. The Go API uses the standard library’s net/http package or frameworks like Gin or Echo and connects to PostgreSQL using libraries like pgx or database/sql. The React frontend is built with Vite and communicates with the API over HTTP.
architecture-beta service db(logos:postgresql)[PostgreSQL] service api(logos:java)[API service] service frontend(logos:react)[React frontend] api:R --> L:db frontend:R --> L:api
This architecture demonstrates a Java API (using Spring Boot) connecting to a PostgreSQL database, with a React frontend consuming the API. The Java API uses Spring Boot with Spring Data JPA and connects to PostgreSQL using JDBC or Spring Data. The React frontend is built with Vite and communicates with the API over HTTP.
You can represent that architecture in an AppHost like this:
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddProject<Projects.Api>("api") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Uses AddProject<Projects.Api>() to reference a .NET project.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addProject("api", "../api/Api.csproj", "https") .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();Uses addProject() to reference the API project.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddUvicornApp("api", "../api", "main:app") .WithUv() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Uses AddUvicornApp() with WithUv() for ASGI apps like FastAPI.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addUvicornApp("api", "../api", "main:app") .withUv() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();Uses addUvicornApp() with withUv() for ASGI apps like FastAPI.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddNodeApp("api", "../api", "server.js") .WithNpm() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Uses AddNodeApp() with WithNpm() for Node.js applications.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addNodeApp("api", "../api", "server.js") .withNpm() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();Uses addNodeApp() with withNpm() for Node.js applications.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddGolangApp("api", "../api") .WithHttpEndpoint(env: "PORT") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Uses AddGolangApp() for Go applications.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddSpringApp("api", "../api", "otel.jar") .WithHttpEndpoint(port: 8080) .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Uses AddSpringApp() for Spring Boot applications.
The AppHost models your distributed application declaratively. Each code sample above shows the same three-tier architecture—PostgreSQL database, API service, and React frontend—but with different API implementations and, when available, different AppHost languages.
In all cases, the PostgreSQL database and React frontend remain identical. Aspire resource references establish dependencies between resources, and the app model ensures services start in the correct order.
Aspire presents the same, consistent model regardless of the language or framework used: services, resources, and the connections between them.
Dissecting the AppHost code
Section titled “Dissecting the AppHost code”Below we highlight the key parts of a typical AppHost to explain what each step does.
var builder = DistributedApplication.CreateBuilder(args);
14 ausgeblendete Zeilen
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddProject<Projects.Api>("api") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();In the non-collapsed lines you:
- Create the distributed application builder with
DistributedApplication.CreateBuilder(args). - Call
Build()to materialize the configuration into a runnable AppHost. - Call
Run()to start orchestration; services launch in dependency order.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
14 ausgeblendete Zeilen
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addProject("api", "../api/Api.csproj", "https") .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();In the non-collapsed lines you:
- Create the distributed application builder with
await createBuilder(). - Call
build()to materialize the configuration into a runnable AppHost. - Call
run()to start orchestration; services launch in dependency order.
var builder = DistributedApplication.CreateBuilder(args);
15 ausgeblendete Zeilen
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddUvicornApp("api", "../api", "main:app") .WithUv() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();In the non-collapsed lines you:
- Create the distributed application builder with
DistributedApplication.CreateBuilder(args). - Call
Build()to materialize the configuration into a runnable AppHost. - Call
Run()to start orchestration; services launch in dependency order.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
15 ausgeblendete Zeilen
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addUvicornApp("api", "../api", "main:app") .withUv() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();In the non-collapsed lines you:
- Create the distributed application builder with
await createBuilder(). - Call
build()to materialize the configuration into a runnable AppHost. - Call
run()to start orchestration; services launch in dependency order.
var builder = DistributedApplication.CreateBuilder(args);
15 ausgeblendete Zeilen
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddNodeApp("api", "../api", "server.js") .WithNpm() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();In the non-collapsed lines you:
- Create the distributed application builder with
DistributedApplication.CreateBuilder(args). - Call
Build()to materialize the configuration into a runnable AppHost. - Call
Run()to start orchestration; services launch in dependency order.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
15 ausgeblendete Zeilen
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addNodeApp("api", "../api", "server.js") .withNpm() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();In the non-collapsed lines you:
- Create the distributed application builder with
await createBuilder(). - Call
build()to materialize the configuration into a runnable AppHost. - Call
run()to start orchestration; services launch in dependency order.
var builder = DistributedApplication.CreateBuilder(args);
15 ausgeblendete Zeilen
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddGolangApp("api", "../api") .WithHttpEndpoint(env: "PORT") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();In the non-collapsed lines you:
- Create the distributed application builder with
DistributedApplication.CreateBuilder(args). - Call
Build()to materialize the configuration into a runnable AppHost. - Call
Run()to start orchestration; services launch in dependency order.
var builder = DistributedApplication.CreateBuilder(args);
15 ausgeblendete Zeilen
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddSpringApp("api", "../api", "otel.jar") .WithHttpEndpoint(port: 8080) .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();In the non-collapsed lines you:
- Create the distributed application builder with
DistributedApplication.CreateBuilder(args). - Call
Build()to materialize the configuration into a runnable AppHost. - Call
Run()to start orchestration; services launch in dependency order.
The AppHost is the blueprint for your distributed application—Aspire manages the rest.
Adding a PostgreSQL resource
Section titled “Adding a PostgreSQL resource”With the builder ready, define resources and services. The snippet below shows how to add a PostgreSQL server and a database:
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
10 ausgeblendete Zeilen
// Add API service and reference the databasevar api = builder.AddProject<Projects.Api>("api") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();How this works:
AddPostgres(“db”)registers a PostgreSQL container nameddb..AddDatabase(“appdata”)creates a database namedappdataon that server..WithDataVolume()provisions a volume so data persists across container restarts.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
10 ausgeblendete Zeilen
// Add API service and reference the databaseconst api = await builder.addProject("api", "../api/Api.csproj", "https") .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();How this works:
await builder.addPostgres(“db”)registers a PostgreSQL server resource nameddb..addDatabase(“appdata”)adds theappdatadatabase to that server..withDataVolume()enables persistent storage for the database container.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
11 ausgeblendete Zeilen
// Add API service and reference the databasevar api = builder.AddUvicornApp("api", "../api", "main:app") .WithUv() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();How this works:
AddPostgres(“db”)registers a PostgreSQL container nameddb..AddDatabase(“appdata”)creates a database namedappdataon that server..WithDataVolume()provisions a volume so data persists across container restarts.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
11 ausgeblendete Zeilen
// Add API service and reference the databaseconst api = await builder.addUvicornApp("api", "../api", "main:app") .withUv() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();How this works:
await builder.addPostgres(“db”)registers a PostgreSQL server resource nameddb..addDatabase(“appdata”)adds theappdatadatabase to that server..withDataVolume()enables persistent storage for the database container.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
11 ausgeblendete Zeilen
// Add API service and reference the databasevar api = builder.AddNodeApp("api", "../api", "server.js") .WithNpm() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();How this works:
AddPostgres(“db”)registers a PostgreSQL container nameddb..AddDatabase(“appdata”)creates a database namedappdataon that server..WithDataVolume()provisions a volume so data persists across container restarts.
import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
11 ausgeblendete Zeilen
// Add API service and reference the databaseconst api = await builder.addNodeApp("api", "../api", "server.js") .withNpm() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();How this works:
await builder.addPostgres(“db”)registers a PostgreSQL server resource nameddb..addDatabase(“appdata”)adds theappdatadatabase to that server..withDataVolume()enables persistent storage for the database container.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
11 ausgeblendete Zeilen
// Add API service and reference the databasevar api = builder.AddGolangApp("api", "../api") .WithHttpEndpoint(env: "PORT") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();How this works:
AddPostgres(“db”)registers a PostgreSQL container nameddb..AddDatabase(“appdata”)creates a database namedappdataon that server..WithDataVolume()provisions a volume so data persists across container restarts.
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
11 ausgeblendete Zeilen
// Add API service and reference the databasevar api = builder.AddSpringApp("api", "../api", "otel.jar") .WithHttpEndpoint(port: 8080) .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();How this works:
AddPostgres(“db”)registers a PostgreSQL container nameddb..AddDatabase(“appdata”)creates a database namedappdataon that server..WithDataVolume()provisions a volume so data persists across container restarts.
Learn more about the official PostgreSQL integration.
Adding an API resource and declaring a dependency
Section titled “Adding an API resource and declaring a dependency”Next, register the API service and wire it to the PostgreSQL resource:
6 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddProject<Projects.Api>("api") .WithReference(postgres) .WaitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();What this does:
AddProject<Projects.Api>(“api”)registers the API project as a service namedapi.WithReference(postgres)injects connection details into the API configuration.WaitFor(postgres)delays startup until PostgreSQL is healthy.
import { createBuilder } from './.modules/aspire.js';
6 ausgeblendete Zeilen
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addProject("api", "../api/Api.csproj", "https") .withReference(postgres) .waitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();What this does:
addProject(“api”, ”../api/Api.csproj”, “https”)registers the API project as a service namedapi.withReference(postgres)wires the database dependency into the API resource.waitFor(postgres)delays startup until PostgreSQL is healthy.
6 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddUvicornApp("api", "../api", "main:app") .WithUv() .WithReference(postgres) .WaitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();What this does:
AddUvicornApp(“api”, ”../api”, “main:app”)registers a Uvicorn-based Python app namedapi.WithUv()configures the app to use the uv package manager.WithReference(postgres)injects connection details into the API configuration.WaitFor(postgres)delays startup until PostgreSQL is healthy.
import { createBuilder } from './.modules/aspire.js';
6 ausgeblendete Zeilen
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addUvicornApp("api", "../api", "main:app") .withUv() .withReference(postgres) .waitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();What this does:
addUvicornApp(“api”, ”../api”, “main:app”)registers a Uvicorn-based Python app namedapi.withUv()enables uv-based dependency management.withReference(postgres)injects the database connection details.waitFor(postgres)delays startup until PostgreSQL is healthy.
6 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddNodeApp("api", "../api", "server.js") .WithNpm() .WithReference(postgres) .WaitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();What this does:
AddNodeApp(“api”, ”../api”, “server.js”)registers a Node.js app namedapi.WithNpm()configures the app to use npm for dependency installation.WithReference(postgres)injects connection details into the API configuration.WaitFor(postgres)delays startup until PostgreSQL is healthy.
import { createBuilder } from './.modules/aspire.js';
6 ausgeblendete Zeilen
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addNodeApp("api", "../api", "server.js") .withNpm() .withReference(postgres) .waitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();What this does:
addNodeApp(“api”, ”../api”, “server.js”)registers a Node.js app namedapi.withNpm()configures npm-based dependency installation.withReference(postgres)injects the database connection details.waitFor(postgres)delays startup until PostgreSQL is healthy.
6 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddGolangApp("api", "../api") .WithHttpEndpoint(env: "PORT") .WithReference(postgres) .WaitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();What this does:
AddGolangApp(“api”, ”../api”)registers a Go app as a service namedapi.WithHttpEndpoint(env: “PORT”)configures the port and sets thePORTenvironment variable.WithReference(postgres)injects connection details into the API configuration.WaitFor(postgres)delays the API startup until PostgreSQL is healthy.
6 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddSpringApp("api", "../api", "otel.jar") .WithHttpEndpoint(port: 8080) .WithReference(postgres) .WaitFor(postgres);
5 ausgeblendete Zeilen
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();What this does:
AddSpringApp(“api”, ”../api”, “otel.jar”)registers a Spring Boot app namedapi.WithHttpEndpoint(port: 8080)exposes the Spring Boot app on port8080.WithReference(postgres)injects connection details into the API configuration.WaitFor(postgres)delays the API startup until PostgreSQL is healthy.
Now that the api service is defined, you can attach the frontend.
Adding a frontend resource
Section titled “Adding a frontend resource”Register the frontend project, declare its dependency on the API, and let the AppHost provide the API address automatically.
11 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddProject<Projects.Api>("api") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Key points:
AddViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.WithHttpEndpoint(env: “PORT”)exposes the app and lets thePORTenvironment variable control the listener.WithReference(api)injects the API base address into the frontend configuration.
import { createBuilder } from './.modules/aspire.js';
11 ausgeblendete Zeilen
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addProject("api", "../api/Api.csproj", "https") .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();Key points:
addViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.withHttpEndpoint({ env: “PORT” })exposes the app and lets thePORTenvironment variable control the listener.withReference(api)injects the API base address into the frontend configuration.
12 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddUvicornApp("api", "../api", "main:app") .WithUv() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Key points:
AddViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.WithHttpEndpoint(env: “PORT”)exposes the app and lets thePORTenvironment variable control the listener.WithReference(api)injects the API base address into the frontend configuration.
import { createBuilder } from './.modules/aspire.js';
12 ausgeblendete Zeilen
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addUvicornApp("api", "../api", "main:app") .withUv() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();Key points:
addViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.withHttpEndpoint({ env: “PORT” })exposes the app and lets thePORTenvironment variable control the listener.withReference(api)injects the API base address into the frontend configuration.
12 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddNodeApp("api", "../api", "server.js") .WithNpm() .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Key points:
AddViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.WithHttpEndpoint(env: “PORT”)exposes the app and lets thePORTenvironment variable control the listener.WithReference(api)injects the API base address into the frontend configuration.
import { createBuilder } from './.modules/aspire.js';
12 ausgeblendete Zeilen
const builder = await createBuilder();
// Add database resourceconst postgres = await builder.addPostgres("db") .addDatabase("appdata") .withDataVolume();
// Add API service and reference the databaseconst api = await builder.addNodeApp("api", "../api", "server.js") .withNpm() .withReference(postgres) .waitFor(postgres);
// Add frontend service and reference the APIawait builder.addViteApp("frontend", "../frontend") .withHttpEndpoint({ env: "PORT" }) .withReference(api);
await builder.build().run();Key points:
addViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.withHttpEndpoint({ env: “PORT” })exposes the app and lets thePORTenvironment variable control the listener.withReference(api)injects the API base address into the frontend configuration.
12 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddGolangApp("api", "../api") .WithHttpEndpoint(env: "PORT") .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Key points:
AddViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.WithHttpEndpoint(env: “PORT”)exposes the app and lets thePORTenvironment variable control the listener.WithReference(api)injects the API base address into the frontend configuration.
12 ausgeblendete Zeilen
var builder = DistributedApplication.CreateBuilder(args);
// Add database resourcevar postgres = builder.AddPostgres("db") .AddDatabase("appdata") .WithDataVolume();
// Add API service and reference the databasevar api = builder.AddSpringApp("api", "../api", "otel.jar") .WithHttpEndpoint(port: 8080) .WithReference(postgres) .WaitFor(postgres);
// Add frontend service and reference the APIbuilder.AddViteApp("frontend", "../frontend") .WithHttpEndpoint(env: "PORT") .WithReference(api);
builder.Build().Run();Key points:
AddViteApp(“frontend”, ”../frontend”)registers the frontend as a service namedfrontend.WithHttpEndpoint(env: “PORT”)exposes the app and lets thePORTenvironment variable control the listener.WithReference(api)injects the API base address into the frontend configuration.
In short: define the backend first (DB → API), then point the UI at the API. The AppHost captures the dependency graph, connection flows, and startup order.
Configuration and networking
Section titled “Configuration and networking”These dependencies and connections are automatically managed by Aspire. The AppHost generates configuration values like connection strings and endpoints, injecting them into services as needed. In the AppHost when you add resources, you name them (e.g., db, api, frontend); Aspire uses these names for DNS resolution, so services can communicate using predictable addresses. Consuming services also rely on these names for configuration injection.
architecture-beta service db(logos:postgresql)[pg] service epr(iconoir:server-connection)[Endpoint Reference] service api(logos:dotnet)[api] service ctr(iconoir:server-connection)[Connection String Reference] service frontend(logos:react)[frontend] db:L <-- R:ctr ctr:L <-- R:api api:L <-- R:epr epr:L <-- R:frontend
The .NET API receives a ConnectionStringReference from PostgreSQL and publishes an EndpointReference that the React frontend consumes. This creates a clear dependency chain: PostgreSQL → .NET API → React frontend.
architecture-beta service db(logos:postgresql)[pg] service epr(iconoir:server-connection)[Endpoint Reference] service api(logos:python)[api] service ctr(iconoir:server-connection)[Connection String Reference] service frontend(logos:react)[frontend] db:L <-- R:ctr ctr:L <-- R:api api:L <-- R:epr epr:L <-- R:frontend
The Python API receives a ConnectionStringReference from PostgreSQL and publishes an EndpointReference that the React frontend consumes. This creates a clear dependency chain: PostgreSQL → Python API → React frontend.
architecture-beta service db(logos:postgresql)[pg] service epr(iconoir:server-connection)[Endpoint Reference] service api(logos:nodejs-icon)[api] service ctr(iconoir:server-connection)[Connection String Reference] service frontend(logos:react)[frontend] db:L <-- R:ctr ctr:L <-- R:api api:L <-- R:epr epr:L <-- R:frontend
The Node.js API receives a ConnectionStringReference from PostgreSQL and publishes an EndpointReference that the React frontend consumes. This creates a clear dependency chain: PostgreSQL → Node.js API → React frontend.
architecture-beta service db(logos:postgresql)[pg] service epr(iconoir:server-connection)[Endpoint Reference] service api(logos:go)[api] service ctr(iconoir:server-connection)[Connection String Reference] service frontend(logos:react)[frontend] db:L <-- R:ctr ctr:L <-- R:api api:L <-- R:epr epr:L <-- R:frontend
The Go API receives a ConnectionStringReference from PostgreSQL and publishes an EndpointReference that the React frontend consumes. This creates a clear dependency chain: PostgreSQL → Go API → React frontend.
architecture-beta service db(logos:postgresql)[pg] service epr(iconoir:server-connection)[Endpoint Reference] service api(logos:java)[api] service ctr(iconoir:server-connection)[Connection String Reference] service frontend(logos:react)[frontend] db:L <-- R:ctr ctr:L <-- R:api api:L <-- R:epr epr:L <-- R:frontend
The Java API receives a ConnectionStringReference from PostgreSQL and publishes an EndpointReference that the React frontend consumes. This creates a clear dependency chain: PostgreSQL → Java API → React frontend.
How these resources communicate
pgpublishes aConnectionStringReference(host, port, database, user, password)—a strongly typed bundle Aspire understands.apideclares a dependency on that reference; Aspire injects the connection string into its config with a unique configuration-flow process that injects settings values, including secrets, parameters, and connection strings for both local runs and deployments.apithen publishes anEndpointReference(its base URL) after its HTTP endpoint is allocated.frontenddepends on that endpoint; Aspire injects the API base URL so no hard-coded addresses are needed.
How the AppHost works
Section titled “How the AppHost works”When you run the AppHost, Aspire performs these core responsibilities:
- Service discovery: Aspire discovers services and resources declared in the AppHost.
- Dependency resolution: Services start in the correct order based on declared dependencies.
- Configuration injection: Connection strings, endpoints, and other config values are injected automatically.
- Health monitoring: Aspire observes service health and can restart services when necessary.
Dive deeper into Aspire’s orchestration and the Resource model.
AppHost structure
Section titled “AppHost structure”The template AppHost is structured in the following ways:
OrdnerAspireApp.AppHost
- apphost.cs dev-time orchestrator
- apphost.run.json
OrdnerAspireApp.AppHost
OrdnerProperties
- launchSettings.json
- appsettings.Development.json
- appsettings.json
- AspireApp.AppHost.csproj
- AppHost.cs dev-time orchestrator
Ordnermy-apphost/
Ordner.modules/ Generated SDK
- …
- apphost.ts dev-time orchestrator
- aspire.config.json
- package.json
- tsconfig.json
AppHost lifecycle events
Section titled “AppHost lifecycle events”You can hook into lifecycle events to run custom logic during startup and resource allocation.
BeforeStartEvent: Raised before the AppHost begins starting services.AfterEndpointsAllocatedEvent: Raised after endpoints are allocated for services.AfterResourcesCreatedEvent: Raised after all resources are created.
For finer-grained lifecycle control, see the well-known lifecycle events.
Best practices
Section titled “Best practices”- Keep the AppHost minimal to start; add complexity only as required.
- Define explicit dependencies with
.WithReference(...)to make wiring obvious. - Use separate configurations for development, testing, and production.
- Pick clear, descriptive names for resources to make debugging and logging easier.