diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 8a706733..f6b541f3 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -356,6 +356,7 @@ "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.36.2.tgz", "integrity": "sha512-QR8NfO7+7DR13kBikhQwAj3IAoptLLNs9DkyKko2M2l3PrqpcpVUnw1JBJ0msGDIwE6tBbua2UeBND48mkh03w==", "license": "MIT", + "peer": true, "dependencies": { "@astrojs/markdown-remark": "^6.3.1", "@astrojs/mdx": "^4.2.3", @@ -2818,6 +2819,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3004,6 +3006,7 @@ "resolved": "https://registry.npmjs.org/astro/-/astro-5.15.9.tgz", "integrity": "sha512-XLDXxu0282cC/oYHswWZm3johGlRvk9rLRS7pWVWSne+HsZe9JgrpHI+vewAJSSNHBGd1aCyaQOElT5RNGe7IQ==", "license": "MIT", + "peer": true, "dependencies": { "@astrojs/compiler": "^2.13.0", "@astrojs/internal-helpers": "0.7.5", @@ -3435,6 +3438,7 @@ "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -3715,6 +3719,7 @@ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10" } @@ -4115,6 +4120,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -6277,6 +6283,7 @@ "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.12.1.tgz", "integrity": "sha512-UlIZrRariB11TY1RtTgUWp65tphtBv4CSq7vyS2ZZ2TgoMjs2nloq+wFqxiwcxlhHUvs7DPGgMjs2aeQxz5h9g==", "license": "MIT", + "peer": true, "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.1", @@ -7527,6 +7534,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -8106,6 +8114,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz", "integrity": "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -8210,6 +8219,7 @@ "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", "integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" } @@ -9309,6 +9319,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -9604,6 +9615,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/src/frontend/sidebar.topics.ts b/src/frontend/sidebar.topics.ts index 11a71013..85e656ba 100644 --- a/src/frontend/sidebar.topics.ts +++ b/src/frontend/sidebar.topics.ts @@ -994,12 +994,13 @@ export const sidebarTopics: StarlightSidebarTopicsUserConfig = [ ] }, { label: "Oracle", slug: "integrations/databases/oracle" }, - { - label: "PostgreSQL", + { label: "PostgreSQL", collapsed: true, items: [ - { label: "Integration overview", slug: "integrations/databases/postgres" }, - { label: "Community extensions", slug: "integrations/databases/postgresql-extensions" } + { label: "Get started", slug: "integrations/databases/postgres/postgres-get-started" }, + { label: "Hosting integration (AppHost)", slug: "integrations/databases/postgres/postgres-host" }, + { label: "Client integration (Your app)", slug: "integrations/databases/postgres/postgres-client" }, + { label: "Community extensions", slug: "integrations/databases/postgres/postgresql-extensions" } ] }, { label: "Qdrant", slug: "integrations/databases/qdrant" }, diff --git a/src/frontend/src/assets/integrations/postgresql/postgresql-dashboard-dark.png b/src/frontend/src/assets/integrations/postgresql/postgresql-dashboard-dark.png new file mode 100644 index 00000000..167845f0 Binary files /dev/null and b/src/frontend/src/assets/integrations/postgresql/postgresql-dashboard-dark.png differ diff --git a/src/frontend/src/assets/integrations/postgresql/postgresql-dashboard-light.png b/src/frontend/src/assets/integrations/postgresql/postgresql-dashboard-light.png new file mode 100644 index 00000000..9afdd914 Binary files /dev/null and b/src/frontend/src/assets/integrations/postgresql/postgresql-dashboard-light.png differ diff --git a/src/frontend/src/assets/integrations/postgresql/postgresql-python-dashboard-dark.png b/src/frontend/src/assets/integrations/postgresql/postgresql-python-dashboard-dark.png new file mode 100644 index 00000000..b50129b6 Binary files /dev/null and b/src/frontend/src/assets/integrations/postgresql/postgresql-python-dashboard-dark.png differ diff --git a/src/frontend/src/assets/integrations/postgresql/postgresql-python-dashboard-light.png b/src/frontend/src/assets/integrations/postgresql/postgresql-python-dashboard-light.png new file mode 100644 index 00000000..f2ea0216 Binary files /dev/null and b/src/frontend/src/assets/integrations/postgresql/postgresql-python-dashboard-light.png differ diff --git a/src/frontend/src/content/docs/integrations/databases/postgres/postgres-client.mdx b/src/frontend/src/content/docs/integrations/databases/postgres/postgres-client.mdx new file mode 100644 index 00000000..10d327a7 --- /dev/null +++ b/src/frontend/src/content/docs/integrations/databases/postgres/postgres-client.mdx @@ -0,0 +1,198 @@ +--- +title: PostgreSQL Client integration reference +description: Learn how to use the Aspire PostgreSQL Client integration to query PostgreSQL databases from your Aspire projects. +--- + +import { Image } from 'astro:assets'; +import InstallPackage from '@components/InstallPackage.astro'; +import InstallDotNetPackage from '@components/InstallDotNetPackage.astro'; +import { Aside, Code, Steps, Tabs, TabItem } from '@astrojs/starlight/components'; +import postgresIcon from '@assets/icons/postgresql-icon.png'; + +PostgreSQL logo + +To get started with the Aspire PostgreSQL integrations, follow the [Get started with PostgreSQL integrations](../postgres-get-started/) guide. + +In this article includes full details about the Aspire PostgreSQL Client integration, which allows you to connect to and interact with PostgreSQL databases from your Aspire consuming projects. + +## Installation + +To get started with the Aspire PostgreSQL client integration, install the [πŸ“¦ Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package in the client-consuming project, that is, the project for the application that uses the PostgreSQL client. The PostgreSQL client integration registers an [NpgsqlDataSource](https://www.npgsql.org/doc/api/Npgsql.NpgsqlDataSource.html) instance that you can use to interact with PostgreSQL. + + + +## Add Npgsql client + +In the `Program.cs` file of your client-consuming project, call the `AddNpgsqlDataSource` extension method on any `IHostApplicationBuilder` to register an `NpgsqlDataSource` for use via the dependency injection container. The method takes a connection name parameter. + +```csharp title="C# β€” Program.cs" +builder.AddNpgsqlDataSource(connectionName: "postgresdb"); +``` + + + +After adding `NpgsqlDataSource` to the builder, you can get the `NpgsqlDataSource` instance using dependency injection. For example, to retrieve your data source object from an example service define it as a constructor parameter and ensure the `ExampleService` class is registered with the dependency injection container: + +```csharp title="C# β€” ExampleService.cs" +public class ExampleService(NpgsqlDataSource dataSource) +{ + // Use dataSource... +} +``` + +## Add keyed Npgsql client + +There might be situations where you want to register multiple `NpgsqlDataSource` instances with different connection names. To register keyed Npgsql clients, call the `AddKeyedNpgsqlDataSource` method: + +```csharp title="C# β€” Program.cs" +builder.AddKeyedNpgsqlDataSource(name: "chat"); +builder.AddKeyedNpgsqlDataSource(name: "queue"); +``` + +Then you can retrieve the `NpgsqlDataSource` instances using dependency injection. For example, to retrieve the connection from an example service: + +```csharp title="C# β€” ExampleService.cs" +public class ExampleService( + [FromKeyedServices("chat")] NpgsqlDataSource chatDataSource, + [FromKeyedServices("queue")] NpgsqlDataSource queueDataSource) +{ + // Use data sources... +} +``` + +## Properties of the PostgreSQL resources + +When you use the `WithReference` method to pass a PostgreSQL server or database resource from the AppHost project to a consuming client project, several properties are available to use in the consuming project. + +Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `Uri` property of a resource called `db1` becomes `DB1_URI`. + +### PostgreSQL server resource + +The PostgreSQL server resource exposes the following connection properties: + +| Property Name | Description | +|---------------|-------------| +| `Host` | The hostname or IP address of the PostgreSQL server | +| `Port` | The port number the PostgreSQL server is listening on | +| `Username` | The username for authentication | +| `Password` | The password for authentication | +| `Uri` | The connection URI in postgresql:// format, with the format `postgresql://{Username}:{Password}@{Host}:{Port}` | +| `JdbcConnectionString` | JDBC-format connection string, with the format `jdbc:postgresql://{Host}:{Port}`. User and password credentials are provided as separate `Username` and `Password` properties. | + +### PostgreSQL database resource + +The PostgreSQL database resource inherits all properties from its parent `PostgresServerResource` and adds: + +| Property Name | Description | +|---------------|-------------| +| `Uri` | The connection URI with the database name, with the format `postgresql://{Username}:{Password}@{Host}:{Port}/{DatabaseName}` | +| `JdbcConnectionString` | JDBC connection string with database name, with the format `jdbc:postgresql://{Host}:{Port}/{DatabaseName}`. User and password credentials are provided as separate `Username` and `Password` properties. | +| `DatabaseName` | The name of the database | + +## Configuration + +The Aspire PostgreSQL integration provides multiple configuration approaches and options to meet the requirements and conventions of your project. + +### Use a connection string + +When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling the `AddNpgsqlDataSource` method: + +```csharp title="C# β€” Program.cs" +builder.AddNpgsqlDataSource("postgresdb"); +``` + +Then the connection string will be retrieved from the `ConnectionStrings` configuration section: + +```json title="JSON β€” appsettings.json" +{ + "ConnectionStrings": { + "postgresdb": "Host=myserver;Database=postgresdb" + } +} +``` + +For more information, see the [ConnectionString](https://www.npgsql.org/doc/connection-string-parameters.html). + +### Use configuration providers + +The Aspire PostgreSQL integration supports `Microsoft.Extensions.Configuration`. It loads the `NpgsqlSettings` from `appsettings.json` or other configuration files by using the `Aspire:Npgsql` key. Example `appsettings.json` that configures some of the options: + +The following example shows an `appsettings.json` file that configures some of the available options: + +```json title="JSON β€” appsettings.json" +{ + "Aspire": { + "Npgsql": { + "ConnectionString": "Host=myserver;Database=postgresdb", + "DisableHealthChecks": false, + "DisableTracing": true, + "DisableMetrics": false + } + } +} +``` + +For the complete PostgreSQL client integration JSON schema, see [Aspire.Npgsql/ConfigurationSchema.json](https://github.com/dotnet/aspire/blob/v9.1.0/src/Components/Aspire.Npgsql/ConfigurationSchema.json). + +### Use inline delegates + +You can also pass the `Action configureSettings` delegate to set up some or all the options inline, for example to disable health checks: + +```csharp title="C# β€” Program.cs" +builder.AddNpgsqlDataSource( + "postgresdb", + static settings => settings.DisableHealthChecks = true); +``` + +## Client integration health checks + +By default, Aspire _client integrations_ have health checks enabled for all services. Similarly, many Aspire _hosting integrations_ also enable health check endpoints. For more information, see: + +- Adds the [`NpgSqlHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs), which verifies that commands can be successfully executed against the underlying Postgres database. +- Integrates with the `/health` HTTP endpoint, which specifies all registered health checks must pass for app to be considered ready to accept traffic + +## Observability and telemetry + +Aspire integrations automatically set up Logging, Tracing, and Metrics configurations, which are sometimes known as *the pillars of observability*. Depending on the backing service, some integrations may only support some of these features. For example, some integrations support logging and tracing, but not metrics. Telemetry features can also be disabled using the techniques presented in the [Configuration](#configuration) section. + +### Logging + +The Aspire PostgreSQL integration uses the following log categories: + +- `Npgsql.Connection` +- `Npgsql.Command` +- `Npgsql.Transaction` +- `Npgsql.Copy` +- `Npgsql.Replication` +- `Npgsql.Exception` + +### Tracing + +The Aspire PostgreSQL integration will emit the following tracing activities using OpenTelemetry: + +- `Npgsql` + +### Metrics + +The Aspire PostgreSQL integration will emit the following metrics using OpenTelemetry: + +- Npgsql: + - `ec_Npgsql_bytes_written_per_second` + - `ec_Npgsql_bytes_read_per_second` + - `ec_Npgsql_commands_per_second` + - `ec_Npgsql_total_commands` + - `ec_Npgsql_current_commands` + - `ec_Npgsql_failed_commands` + - `ec_Npgsql_prepared_commands_ratio` + - `ec_Npgsql_connection_pools` + - `ec_Npgsql_multiplexing_average_commands_per_batch` + - `ec_Npgsql_multiplexing_average_write_time_per_batch` \ No newline at end of file diff --git a/src/frontend/src/content/docs/integrations/databases/postgres/postgres-get-started.mdx b/src/frontend/src/content/docs/integrations/databases/postgres/postgres-get-started.mdx new file mode 100644 index 00000000..0744b053 --- /dev/null +++ b/src/frontend/src/content/docs/integrations/databases/postgres/postgres-get-started.mdx @@ -0,0 +1,183 @@ +--- +title: Get started with the PostgreSQL integrations +description: Learn how to set up the Aspire PostgreSQL Hosting and Client integrations simply. +--- + +import { Image } from 'astro:assets'; +import { Kbd } from 'starlight-kbd/components'; +import InstallPackage from '@components/InstallPackage.astro'; +import InstallDotNetPackage from '@components/InstallDotNetPackage.astro'; +import { Aside, CardGrid, LinkCard, Code, Steps, Tabs, TabItem } from '@astrojs/starlight/components'; +import PivotSelector from '@components/PivotSelector.astro'; +import Pivot from '@components/Pivot.astro'; +import ThemeImage from '@components/ThemeImage.astro'; +import postgresIcon from '@assets/icons/postgresql-icon.png'; + +PostgreSQL logo + +[PostgreSQL](https://www.postgresql.org/) is a powerful, open source object-relational database system with many years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. The Aspire PostgreSQL integration provides a way to connect to existing PostgreSQL databases, or create new instances from the [`docker.io/library/postgres` container image](https://hub.docker.com/_/postgres). + +In this introduction, you'll see how to install and use the Aspire PostgreSQL integrations in a simple configuration. If you already have this knowledge, see [PostgreSQL Hosting integration](../postgres-host/) for full reference details. + + + +## Set up the hosting integration + +To begin, install the Aspire PostgreSQL Hosting integration in your Aspire AppHost project. This integration allows you to create and manage PostgreSQL database instances from your Aspire hosting projects: + + + +Next, in the AppHost project, create instances of PostgreSQL server and database resources, then pass the database to the consuming client projects: + +```csharp title="C# β€” AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var postgres = builder.AddPostgres("postgres"); +var postgresdb = postgres.AddDatabase("postgresdb"); + +var exampleProject = builder.AddProject("apiservice") + .WithReference(postgresdb); +``` + + + +## Configuration properties of the PostgreSQL resources + +When you use the `WithReference` method to pass a PostgreSQL server or database resource from the AppHost project to a consuming client project, Aspire injects several configuration properties that you can use in the consuming project. + +Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `Uri` property of a resource called `db1` becomes `DB1_URI`. + +### PostgreSQL server resource + +The PostgreSQL server resource exposes the following connection properties: + +| Property Name | Description | +|---------------|-------------| +| `Host` | The hostname or IP address of the PostgreSQL server | +| `Port` | The port number the PostgreSQL server is listening on | +| `Username` | The username for authentication | +| `Password` | The password for authentication | +| `Uri` | The connection URI in postgresql:// format, with the format `postgresql://{Username}:{Password}@{Host}:{Port}` | +| `JdbcConnectionString` | JDBC-format connection string, with the format `jdbc:postgresql://{Host}:{Port}`. User and password credentials are provided as separate `Username` and `Password` properties. | + +### PostgreSQL database resource + +The PostgreSQL database resource inherits all properties from its parent `PostgresServerResource` and adds: + +| Property Name | Description | +|---------------|-------------| +| `Uri` | The connection URI with the database name, with the format `postgresql://{Username}:{Password}@{Host}:{Port}/{DatabaseName}` | +| `JdbcConnectionString` | JDBC connection string with database name, with the format `jdbc:postgresql://{Host}:{Port}/{DatabaseName}`. User and password credentials are provided as separate `Username` and `Password` properties. | +| `Database` | The name of the database | + +## Set up the client integration + +Now that the hosting integration is ready, the next step is to install and configure the client integration in any projects that need to use it. + + + + + +In each of these consuming client projects, install the Aspire PostgreSQL client integration: + + + +In the `Program.cs` file of your client-consuming project, call the `AddNpgsqlDataSource` extension method on any `IHostApplicationBuilder` to register an `NpgsqlDataSource` for use via the dependency injection container. The method takes a connection name parameter. + +```csharp title="C# β€” Program.cs" +builder.AddNpgsqlDataSource(connectionName: "postgresdb"); +``` + + + +After adding `NpgsqlDataSource` to the builder, you can get the `NpgsqlDataSource` instance using dependency injection. For example, to retrieve your data source object from an example service define it as a constructor parameter and ensure the `ExampleService` class is registered with the dependency injection container: + +```csharp title="C# β€” ExampleService.cs" +public class ExampleService(NpgsqlDataSource dataSource) +{ + // Use dataSource... +} +``` + +You can use environment variables to obtain the configuration properties that Aspire injected when you called the `WithReference` method in the AppHost project: + +```csharp title="C# - Obtain configuration properties" +string databasename = builder.Configuration.GetValue("POSTGRESDB_DATABASENAME"); +``` + + + + + + +You can use environment variables to obtain the configuration properties that Aspire injected when you called the `WithReference` method in the AppHost project: + +```python title="Python - Obtain configuration properties" +databasename = os.environ.get("POSTGRESDB_DATABASENAME") +``` + + + +## Completed solution + +import postgresqlDashboardLight from '@assets/integrations/postgresql/postgresql-dashboard-light.png'; +import postgresqlDashboardDark from '@assets/integrations/postgresql/postgresql-dashboard-dark.png'; +import postgresqlPythonDashboardLight from '@assets/integrations/postgresql/postgresql-python-dashboard-light.png'; +import postgresqlPythonDashboardDark from '@assets/integrations/postgresql/postgresql-python-dashboard-dark.png'; + +In an Aspire solution that uses the PostgreSQL integrations, the **Resources** page includes the PostgreSQL instance: + + + + + + + + + + + + + +## Next steps + +Now, that you have an Aspire app with PostgreSQL integrations up and running, you can use the following reference documents to learn how to configure and interact with the PostgreSQL resources: + + + + \ No newline at end of file diff --git a/src/frontend/src/content/docs/integrations/databases/postgres.mdx b/src/frontend/src/content/docs/integrations/databases/postgres/postgres-host.mdx similarity index 64% rename from src/frontend/src/content/docs/integrations/databases/postgres.mdx rename to src/frontend/src/content/docs/integrations/databases/postgres/postgres-host.mdx index 5f4a44fe..fa1f0b23 100644 --- a/src/frontend/src/content/docs/integrations/databases/postgres.mdx +++ b/src/frontend/src/content/docs/integrations/databases/postgres/postgres-host.mdx @@ -1,5 +1,6 @@ --- -title: PostgreSQL integration +title: PostgreSQL Hosting integration +description: Learn how to use the Aspire PostgreSQL Hosting integration to orchestrate and confgure a PostgreSQL database in an Aspire solution. --- import { Image } from 'astro:assets'; @@ -17,9 +18,11 @@ import postgresIcon from '@assets/icons/postgresql-icon.png'; data-zoom-off /> -[PostgreSQL](https://www.postgresql.org/) is a powerful, open source object-relational database system with many years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. The Aspire PostgreSQL integration provides a way to connect to existing PostgreSQL databases, or create new instances from the [`docker.io/library/postgres` container image](https://hub.docker.com/_/postgres). +To get started with the Aspire PostgreSQL integrations, follow the [Get started with PostgreSQL integrations](../postgres-get-started/) guide. -## Hosting integration +This article includes full details on the Aspire PostgreSQL Hosting integration, which allows you to model PostgreSQL server and database resources in your [`AppHost`](/get-started/welcome/) project. + +## Installation The PostgreSQL hosting integration models various PostgreSQL resources as the following types. @@ -32,7 +35,7 @@ To access these types and APIs for expressing them as resources in your [`AppHos -### Add PostgreSQL server resource +## Add PostgreSQL server resource In your AppHost project, call `AddPostgres` on the `builder` instance to add a PostgreSQL server resource then call `AddDatabase` on the `postgres` instance to add a database resource as shown in the following example: @@ -42,7 +45,7 @@ var builder = DistributedApplication.CreateBuilder(args); var postgres = builder.AddPostgres("postgres"); var postgresdb = postgres.AddDatabase("postgresdb"); -var exampleProject = builder.AddProject() +var exampleProject = builder.AddProject("apiservice") .WithReference(postgresdb); // After adding all resources, run the app... @@ -64,7 +67,11 @@ var exampleProject = builder.AddProject() If you'd rather connect to an existing PostgreSQL server, chain a call to `AsExisting` insteadβ€”passing the appropriate parameters. -### Add PostgreSQL resource with database scripts + + +## Add PostgreSQL resource with database scripts By default, when you add a `PostgresDatabaseResource`, it relies on the following script to create the database: @@ -102,7 +109,7 @@ The preceding example creates a database named `app_db`. The script is run when The connect to a database command (`\c`) isn't supported when using the creation script. -### Add PostgreSQL pgAdmin resource +## Add PostgreSQL pgAdmin resource When adding PostgreSQL resources to the `builder` with the `AddPostgres` method, you can chain calls to `WithPgAdmin` to add the [**dpage/pgadmin4**](https://www.pgadmin.org/) container. This container is a cross-platform client for PostgreSQL databases, that serves a web-based admin dashboard. Consider the following example: @@ -122,7 +129,7 @@ var exampleProject = builder.AddProject() The preceding code adds a container based on the `docker.io/dpage/pgadmin4` image. The container is used to manage the PostgreSQL server and database resources. The `WithPgAdmin` method adds a container that serves a web-based admin dashboard for PostgreSQL databases. -#### Configure the pgAdmin host port +### Configure the pgAdmin host port To configure the host port for the pgAdmin container, call the `WithHostPort` method on the PostgreSQL server resource. The following example shows how to configure the host port for the pgAdmin container: @@ -142,7 +149,7 @@ var exampleProject = builder.AddProject() The preceding code adds and configures the host port for the pgAdmin container. The host port is otherwise randomly assigned. -### Add PostgreSQL pgWeb resource +## Add PostgreSQL pgWeb resource When adding PostgreSQL resources to the `builder` with the `AddPostgres` method, you can chain calls to `WithPgWeb` to add the [**sosedoff/pgweb**](https://sosedoff.github.io/pgweb/) container. This container is a cross-platform client for PostgreSQL databases, that serves a web-based admin dashboard. Consider the following example: @@ -162,7 +169,7 @@ var exampleProject = builder.AddProject() The preceding code adds a container based on the `docker.io/sosedoff/pgweb` image. All registered `PostgresDatabaseResource` instances are used to create a configuration file per instance, and each config is bound to the **pgweb** container bookmark directory. For more information, see [PgWeb docs: Server connection bookmarks](https://github.com/sosedoff/pgweb/wiki/Server-Connection-Bookmarks). -#### Configure the pgWeb host port +### Configure the pgWeb host port To configure the host port for the pgWeb container, call the `WithHostPort` method on the PostgreSQL server resource. The following example shows how to configure the host port for the pgAdmin container: @@ -182,7 +189,7 @@ var exampleProject = builder.AddProject() The preceding code adds and configures the host port for the pgWeb container. The host port is otherwise randomly assigned. -### Add PostgreSQL server resource with data volume +## Add PostgreSQL server resource with data volume To add a data volume to the PostgreSQL server resource, call the `WithDataVolume` method on the PostgreSQL server resource: @@ -220,7 +227,7 @@ The data volume is used to persist the PostgreSQL server data outside the lifecy ``` -### Add PostgreSQL server resource with data bind mount +## Add PostgreSQL server resource with data bind mount To add a data bind mount to the PostgreSQL server resource, call the `WithDataBindMount` method: @@ -246,7 +253,7 @@ var exampleProject = builder.AddProject() Data bind mounts rely on the host machine's filesystem to persist the PostgreSQL server data across container restarts. The data bind mount is mounted at the `C:\PostgreSQL\Data` on Windows (or `/PostgreSQL/Data` on Unix) path on the host machine in the PostgreSQL server container. For more information on data bind mounts, see [Docker docs: Bind mounts](https://docs.docker.com/engine/storage/bind-mounts). -### Add PostgreSQL server resource with init bind mount +## Add PostgreSQL server resource with init bind mount To add an init bind mount to the PostgreSQL server resource, call the `WithInitBindMount` method: @@ -266,7 +273,7 @@ var exampleProject = builder.AddProject() The init bind mount relies on the host machine's filesystem to initialize the PostgreSQL server database with the containers _init_ folder. This folder is used for initialization, running any executable shell scripts or _.sql_ command files after the _postgres-data_ folder is created. The init bind mount is mounted at the `C:\PostgreSQL\Init` on Windows (or `/PostgreSQL/Init` on Unix) path on the host machine in the PostgreSQL server container. -### Add PostgreSQL server resource with parameters +## Add PostgreSQL server resource with parameters When you want to explicitly provide the username and password used by the container image, you can provide these credentials as parameters. Consider the following alternative example: @@ -285,154 +292,8 @@ var exampleProject = builder.AddProject() // After adding all resources, run the app... ``` -### Hosting integration health checks +## Hosting integration health checks The PostgreSQL hosting integration automatically adds a health check for the PostgreSQL server resource. The health check verifies that the PostgreSQL server is running and that a connection can be established to it. -The hosting integration relies on the [πŸ“¦ AspNetCore.HealthChecks.Npgsql](https://www.nuget.org/packages/AspNetCore.HealthChecks.Npgsql) NuGet package. - -## Client integration - -To get started with the Aspire PostgreSQL client integration, install the [πŸ“¦ Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package in the client-consuming project, that is, the project for the application that uses the PostgreSQL client. The PostgreSQL client integration registers an [NpgsqlDataSource](https://www.npgsql.org/doc/api/Npgsql.NpgsqlDataSource.html) instance that you can use to interact with PostgreSQL. - - - -### Add Npgsql client - -In the `Program.cs` file of your client-consuming project, call the `AddNpgsqlDataSource` extension method on any `IHostApplicationBuilder` to register an `NpgsqlDataSource` for use via the dependency injection container. The method takes a connection name parameter. - -```csharp title="C# β€” Program.cs" -builder.AddNpgsqlDataSource(connectionName: "postgresdb"); -``` - - - -After adding `NpgsqlDataSource` to the builder, you can get the `NpgsqlDataSource` instance using dependency injection. For example, to retrieve your data source object from an example service define it as a constructor parameter and ensure the `ExampleService` class is registered with the dependency injection container: - -```csharp title="C# β€” ExampleService.cs" -public class ExampleService(NpgsqlDataSource dataSource) -{ - // Use dataSource... -} -``` - -### Add keyed Npgsql client - -There might be situations where you want to register multiple `NpgsqlDataSource` instances with different connection names. To register keyed Npgsql clients, call the `AddKeyedNpgsqlDataSource` method: - -```csharp title="C# β€” Program.cs" -builder.AddKeyedNpgsqlDataSource(name: "chat"); -builder.AddKeyedNpgsqlDataSource(name: "queue"); -``` - -Then you can retrieve the `NpgsqlDataSource` instances using dependency injection. For example, to retrieve the connection from an example service: - -```csharp title="C# β€” ExampleService.cs" -public class ExampleService( - [FromKeyedServices("chat")] NpgsqlDataSource chatDataSource, - [FromKeyedServices("queue")] NpgsqlDataSource queueDataSource) -{ - // Use data sources... -} -``` - -### Configuration - -The Aspire PostgreSQL integration provides multiple configuration approaches and options to meet the requirements and conventions of your project. - -#### Use a connection string - -When using a connection string from the `ConnectionStrings` configuration section, you can provide the name of the connection string when calling the `AddNpgsqlDataSource` method: - -```csharp title="C# β€” Program.cs" -builder.AddNpgsqlDataSource("postgresdb"); -``` - -Then the connection string will be retrieved from the `ConnectionStrings` configuration section: - -```json title="JSON β€” appsettings.json" -{ - "ConnectionStrings": { - "postgresdb": "Host=myserver;Database=postgresdb" - } -} -``` - -For more information, see the [ConnectionString](https://www.npgsql.org/doc/connection-string-parameters.html). - -#### Use configuration providers - -The Aspire PostgreSQL integration supports `Microsoft.Extensions.Configuration`. It loads the `NpgsqlSettings` from `appsettings.json` or other configuration files by using the `Aspire:Npgsql` key. Example `appsettings.json` that configures some of the options: - -The following example shows an `appsettings.json` file that configures some of the available options: - -```json title="JSON β€” appsettings.json" -{ - "Aspire": { - "Npgsql": { - "ConnectionString": "Host=myserver;Database=postgresdb", - "DisableHealthChecks": false, - "DisableTracing": true, - "DisableMetrics": false - } - } -} -``` - -For the complete PostgreSQL client integration JSON schema, see [Aspire.Npgsql/ConfigurationSchema.json](https://github.com/dotnet/aspire/blob/v9.1.0/src/Components/Aspire.Npgsql/ConfigurationSchema.json). - -#### Use inline delegates - -You can also pass the `Action configureSettings` delegate to set up some or all the options inline, for example to disable health checks: - -```csharp title="C# β€” Program.cs" -builder.AddNpgsqlDataSource( - "postgresdb", - static settings => settings.DisableHealthChecks = true); -``` - -### Client integration health checks - -By default, Aspire _client integrations_ have health checks enabled for all services. Similarly, many Aspire _hosting integrations_ also enable health check endpoints. For more information, see: - -- Adds the [`NpgSqlHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs), which verifies that commands can be successfully executed against the underlying Postgres database. -- Integrates with the `/health` HTTP endpoint, which specifies all registered health checks must pass for app to be considered ready to accept traffic - -### Observability and telemetry - -Aspire integrations automatically set up Logging, Tracing, and Metrics configurations, which are sometimes known as *the pillars of observability*. Depending on the backing service, some integrations may only support some of these features. For example, some integrations support logging and tracing, but not metrics. Telemetry features can also be disabled using the techniques presented in the [Configuration](#configuration) section. - -#### Logging - -The Aspire PostgreSQL integration uses the following log categories: - -- `Npgsql.Connection` -- `Npgsql.Command` -- `Npgsql.Transaction` -- `Npgsql.Copy` -- `Npgsql.Replication` -- `Npgsql.Exception` - -#### Tracing - -The Aspire PostgreSQL integration will emit the following tracing activities using OpenTelemetry: - -- `Npgsql` - -#### Metrics - -The Aspire PostgreSQL integration will emit the following metrics using OpenTelemetry: - -- Npgsql: - - `ec_Npgsql_bytes_written_per_second` - - `ec_Npgsql_bytes_read_per_second` - - `ec_Npgsql_commands_per_second` - - `ec_Npgsql_total_commands` - - `ec_Npgsql_current_commands` - - `ec_Npgsql_failed_commands` - - `ec_Npgsql_prepared_commands_ratio` - - `ec_Npgsql_connection_pools` - - `ec_Npgsql_multiplexing_average_commands_per_batch` - - `ec_Npgsql_multiplexing_average_write_time_per_batch` \ No newline at end of file +The hosting integration relies on the [πŸ“¦ AspNetCore.HealthChecks.Npgsql](https://www.nuget.org/packages/AspNetCore.HealthChecks.Npgsql) NuGet package. \ No newline at end of file diff --git a/src/frontend/src/content/docs/integrations/databases/postgresql-extensions.mdx b/src/frontend/src/content/docs/integrations/databases/postgres/postgresql-extensions.mdx similarity index 100% rename from src/frontend/src/content/docs/integrations/databases/postgresql-extensions.mdx rename to src/frontend/src/content/docs/integrations/databases/postgres/postgresql-extensions.mdx