-
Notifications
You must be signed in to change notification settings - Fork 236
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add sample showing how to use the support in Aspire.Hosting for datab…
…ase containers (#61) * Updating samples for preview.2 * Skip sign check on workload install for now * Update NuGet.config * Update to latest preview.2 build * Update to latest preview.2 build * Fix node sample * Update the version of preview2 to the latest * Updated the dapr sample and instructions * Update Dapr README to call out dapr init (#66) * Update to latest package versions * WIP * Added DatabaseContainers sample Fixes #60 * Tweaks * Inject connection from DI instead of DataSource * Update samples/DatabaseContainers/README.md Co-authored-by: Bradley Grainger <[email protected]> * Prepare for release --------- Co-authored-by: David Fowler <[email protected]> Co-authored-by: Balamurugan Chirtsabesan <[email protected]> Co-authored-by: Bradley Grainger <[email protected]>
- Loading branch information
1 parent
f67105c
commit 04c1f43
Showing
23 changed files
with
650 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
samples/DatabaseContainers/DatabaseContainers.ApiService/ApiEndpoints.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using Dapper; | ||
using Microsoft.Data.SqlClient; | ||
using MySqlConnector; | ||
using Npgsql; | ||
|
||
namespace DatabaseContainers.ApiService; | ||
|
||
public static class ApiEndpoints | ||
{ | ||
public static WebApplication MapTodosApi(this WebApplication app) | ||
{ | ||
app.MapGet("/todos", async (NpgsqlConnection db) => | ||
{ | ||
const string sql = """ | ||
SELECT Id, Title, IsComplete | ||
FROM Todos | ||
"""; | ||
|
||
return await db.QueryAsync<Todo>(sql); | ||
}); | ||
|
||
app.MapGet("/todos/{id}", async (int id, NpgsqlConnection db) => | ||
{ | ||
const string sql = """ | ||
SELECT Id, Title, IsComplete | ||
FROM Todos | ||
WHERE Id = @id | ||
"""; | ||
|
||
return await db.QueryFirstOrDefaultAsync<Todo>(sql, new { id }) is { } todo | ||
? Results.Ok(todo) | ||
: Results.NotFound(); | ||
}); | ||
|
||
return app; | ||
} | ||
|
||
public static WebApplication MapCatalogApi(this WebApplication app) | ||
{ | ||
app.MapGet("/catalog", async (MySqlConnection db) => | ||
{ | ||
const string sql = """ | ||
SELECT Id, Name, Description, Price | ||
FROM catalog | ||
"""; | ||
|
||
return await db.QueryAsync<CatalogItem>(sql); | ||
}); | ||
|
||
app.MapGet("/catalog/{id}", async (int id, MySqlConnection db) => | ||
{ | ||
const string sql = """ | ||
SELECT Id, Name, Description, Price | ||
FROM catalog | ||
WHERE Id = @id | ||
"""; | ||
|
||
return await db.QueryFirstOrDefaultAsync<CatalogItem>(sql, new { id }) is { } item | ||
? Results.Ok(item) | ||
: Results.NotFound(); | ||
}); | ||
|
||
return app; | ||
} | ||
|
||
public static WebApplication MapAddressBookApi(this WebApplication app) | ||
{ | ||
app.MapGet("/addressbook", async (SqlConnection db) => | ||
{ | ||
const string sql = """ | ||
SELECT Id, FirstName, LastName, Email, Phone | ||
FROM Contacts | ||
"""; | ||
|
||
return await db.QueryAsync<Contact>(sql); | ||
}); | ||
|
||
app.MapGet("/addressbook/{id}", async (int id, SqlConnection db) => | ||
{ | ||
const string sql = """ | ||
SELECT Id, FirstName, LastName, Email, Phone | ||
FROM Contacts | ||
WHERE Id = @id | ||
"""; | ||
|
||
return await db.QueryFirstOrDefaultAsync<Contact>(sql, new { id }) is { } contact | ||
? Results.Ok(contact) | ||
: Results.NotFound(); | ||
}); | ||
|
||
return app; | ||
} | ||
} | ||
|
||
public record Todo(int Id, string Title, bool IsComplete); | ||
|
||
public record CatalogItem(int Id, string Name, string Description, decimal Price); | ||
|
||
public record Contact(int Id, string FirstName, string LastName, string Email, string? Phone); |
22 changes: 22 additions & 0 deletions
22
...les/DatabaseContainers/DatabaseContainers.ApiService/DatabaseContainers.ApiService.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DatabaseContainers.ServiceDefaults\DatabaseContainers.ServiceDefaults.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Aspire.Microsoft.Data.SqlClient" /> | ||
<PackageReference Include="Aspire.Npgsql" /> | ||
<PackageReference Include="Aspire.MySqlConnector" /> | ||
<PackageReference Include="Dapper" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" /> | ||
</ItemGroup> | ||
|
||
</Project> |
34 changes: 34 additions & 0 deletions
34
samples/DatabaseContainers/DatabaseContainers.ApiService/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using DatabaseContainers.ApiService; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
// Add service defaults & Aspire components. | ||
builder.AddServiceDefaults(); | ||
|
||
builder.AddNpgsqlDataSource("Todos"); | ||
builder.AddMySqlDataSource("Catalog"); | ||
builder.AddSqlServerClient("AddressBook"); | ||
|
||
// Add services to the container. | ||
builder.Services.AddProblemDetails(); | ||
builder.Services.AddEndpointsApiExplorer(); | ||
builder.Services.AddSwaggerGen(); | ||
|
||
var app = builder.Build(); | ||
|
||
// Configure the HTTP request pipeline. | ||
app.UseExceptionHandler(); | ||
|
||
app.UseSwagger(); | ||
if (app.Environment.IsDevelopment()) | ||
{ | ||
app.UseSwaggerUI(); | ||
} | ||
|
||
app.MapTodosApi(); | ||
app.MapCatalogApi(); | ||
app.MapAddressBookApi(); | ||
|
||
app.MapDefaultEndpoints(); | ||
|
||
app.Run(); |
15 changes: 15 additions & 0 deletions
15
samples/DatabaseContainers/DatabaseContainers.ApiService/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"profiles": { | ||
"http": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"applicationUrl": "http://localhost:5468", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
samples/DatabaseContainers/DatabaseContainers.ApiService/appsettings.Development.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
samples/DatabaseContainers/DatabaseContainers.ApiService/appsettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
}, | ||
"AllowedHosts": "*" | ||
} |
25 changes: 25 additions & 0 deletions
25
samples/DatabaseContainers/DatabaseContainers.ApiService/data/mysql/init.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
-- MySql init script | ||
|
||
-- NOTE: MySql database and table names are case-sensitive on non-Windows platforms! | ||
-- Column names are always case-insensitive. | ||
|
||
-- Create the Catalog table | ||
CREATE TABLE IF NOT EXISTS `catalog` | ||
( | ||
`id` int(11) NOT NULL AUTO_INCREMENT, | ||
`name` varchar(255) NOT NULL, | ||
`description` varchar(255) NOT NULL, | ||
`price` DECIMAL(18,2) NOT NULL, | ||
PRIMARY KEY (`id`) | ||
); | ||
|
||
-- Insert some sample data into the Catalog table only if the table is empty | ||
INSERT INTO catalog (name, description, price) | ||
SELECT * | ||
FROM ( | ||
SELECT '.NET Bot Black Hoodie', 'This hoodie will keep you warm while looking cool and representing .NET!', 19.5 UNION ALL | ||
SELECT '.NET Black & White Mug', 'The perfect place to keep your favorite beverage while you code.', 8.5 UNION ALL | ||
SELECT 'Prism White T-Shirt', "It's a t-shirt, it's white, and it can be yours.", 12 | ||
) data | ||
-- This clause ensures the rows are only inserted if the table is empty | ||
WHERE NOT EXISTS (SELECT NULL FROM catalog) |
17 changes: 17 additions & 0 deletions
17
samples/DatabaseContainers/DatabaseContainers.ApiService/data/postgres/init.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
-- Postgres init script | ||
|
||
-- Create the Todos table | ||
CREATE TABLE IF NOT EXISTS Todos | ||
( | ||
Id SERIAL PRIMARY KEY, | ||
Title text UNIQUE NOT NULL, | ||
IsComplete boolean NOT NULL DEFAULT false | ||
); | ||
|
||
-- Insert some sample data into the Todos table | ||
INSERT INTO Todos (Title, IsComplete) | ||
VALUES | ||
('Give the dog a bath', false), | ||
('Wash the dishes', false), | ||
('Do the groceries', false) | ||
ON CONFLICT DO NOTHING; |
46 changes: 46 additions & 0 deletions
46
samples/DatabaseContainers/DatabaseContainers.ApiService/data/sqlserver/init.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
-- SQL Server init script | ||
|
||
-- Create the AddressBook database | ||
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = N'AddressBook') | ||
BEGIN | ||
CREATE DATABASE AddressBook; | ||
END; | ||
GO | ||
|
||
USE AddressBook; | ||
GO | ||
|
||
-- Create the Contacts table | ||
IF OBJECT_ID(N'Contacts', N'U') IS NULL | ||
BEGIN | ||
CREATE TABLE Contacts | ||
( | ||
Id INT PRIMARY KEY IDENTITY(1,1) , | ||
FirstName VARCHAR(255) NOT NULL, | ||
LastName VARCHAR(255) NOT NULL, | ||
Email VARCHAR(255) NULL, | ||
Phone VARCHAR(255) NULL | ||
); | ||
END; | ||
GO | ||
|
||
-- Ensure that either the Email or Phone column is populated | ||
IF OBJECT_ID(N'chk_Contacts_Email_Phone', N'C') IS NULL | ||
BEGIN | ||
ALTER TABLE Contacts | ||
ADD CONSTRAINT chk_Contacts_Email_Phone CHECK | ||
( | ||
Email IS NOT NULL OR Phone IS NOT NULL | ||
); | ||
END; | ||
GO | ||
|
||
-- Insert some sample data into the Contacts table | ||
IF (SELECT COUNT(*) FROM Contacts) = 0 | ||
BEGIN | ||
INSERT INTO Contacts (FirstName, LastName, Email, Phone) | ||
VALUES | ||
('John', 'Doe', '[email protected]', '555-123-4567'), | ||
('Jane', 'Doe', '[email protected]', '555-234-5678'); | ||
END; | ||
GO |
19 changes: 19 additions & 0 deletions
19
samples/DatabaseContainers/DatabaseContainers.AppHost/DatabaseContainers.AppHost.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<IsAspireHost>true</IsAspireHost> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DatabaseContainers.ApiService\DatabaseContainers.ApiService.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Aspire.Hosting" /> | ||
</ItemGroup> | ||
|
||
</Project> |
42 changes: 42 additions & 0 deletions
42
samples/DatabaseContainers/DatabaseContainers.AppHost/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
var builder = DistributedApplication.CreateBuilder(args); | ||
|
||
// PostgreSQL container is configured to use trust authentication by default so no password is required | ||
// and supports setting the default database name via an environment variable & running *.sql/*.sh scripts in a bind mount. | ||
var todosDbName = "Todos"; | ||
var todosDb = builder.AddPostgresContainer("postgres") | ||
// Set the name of the default database to auto-create on container startup. | ||
.WithEnvironment("POSTGRES_DB", todosDbName) | ||
// Mount the SQL scripts directory into the container so that the init scripts run. | ||
.WithVolumeMount("../DatabaseContainers.ApiService/data/postgres", "/docker-entrypoint-initdb.d", VolumeMountType.Bind) | ||
// Add the default database to the application model so that it can be referenced by other resources. | ||
.AddDatabase(todosDbName); | ||
|
||
// MySql container is configured with an auto-generated password by default | ||
// and supports setting the default database name via an environment variable & running *.sql/*.sh scripts in a bind mount. | ||
var catalogDbName = "catalog"; // MySql database & table names are case-sensitive on non-Windows. | ||
var catalogDb = builder.AddMySqlContainer("mysql") | ||
// Set the name of the database to auto-create on container startup. | ||
.WithEnvironment("MYSQL_DATABASE", catalogDbName) | ||
// Mount the SQL scripts directory into the container so that the init scripts run. | ||
.WithVolumeMount("../DatabaseContainers.ApiService/data/mysql", "/docker-entrypoint-initdb.d", VolumeMountType.Bind) | ||
// Add the database to the application model so that it can be referenced by other resources. | ||
.AddDatabase(catalogDbName); | ||
|
||
// SQL Server container is configured with an auto-generated password by default | ||
// but doesn't support any auto-creation of databases or running scripts on startup so we have to do it manually. | ||
var addressBookDb = builder.AddSqlServerContainer("sqlserver") | ||
// Mount the init scripts directory into the container. | ||
.WithVolumeMount("./sqlserverconfig", "/usr/config", VolumeMountType.Bind) | ||
// Mount the SQL scripts directory into the container so that the init scripts run. | ||
.WithVolumeMount("../DatabaseContainers.ApiService/data/sqlserver", "/docker-entrypoint-initdb.d", VolumeMountType.Bind) | ||
// Run the custom entrypoint script on startup. | ||
.WithArgs("/usr/config/entrypoint.sh") | ||
// Add the database to the application model so that it can be referenced by other resources. | ||
.AddDatabase("AddressBook"); | ||
|
||
builder.AddProject<Projects.DatabaseContainers_ApiService>("apiservice") | ||
.WithReference(todosDb) | ||
.WithReference(catalogDb) | ||
.WithReference(addressBookDb); | ||
|
||
builder.Build().Run(); |
Oops, something went wrong.