Add standalone OpenAPI mode and code generation setup

Introduced a "--controllers-only" mode in the API for serving OpenAPI endpoints exclusively. Added scripts, Docker configurations, and run settings to enable automated code generation for the Palantir client. Removed obsolete EF metadata target file.
This commit is contained in:
Christian Werner 2025-05-28 03:32:28 +02:00
parent 60589ba45f
commit 3e830d2488
7 changed files with 92 additions and 30 deletions

2
docker/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
code-gen/
!code-gen/**/docker-compose.yml

View File

@ -0,0 +1,42 @@
services:
palantir:
image: mcr.microsoft.com/dotnet/sdk:9.0
container_name: codegen-backend
volumes:
- ./dotnet:/app/
working_dir: /app
restart: no
command: >
dotnet
run
--project Suspectus.Gandalf.Palantir.Api
-v n
--urls "http://0.0.0.0:5035"
-- --controllers-only
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:5035/openapi/v1.json" ]
interval: 5s
timeout: 3s
retries: 100
start_period: 40s
start_interval: 20s
typescript-gen:
image: swaggerapi/swagger-codegen-cli-v3
container_name: codegen-cli
command: >
config-help
-l typescript-angular
# generate
# -i http://palantir:5035/openapi/v1.json
# -l csharp
# -o /local
# -c /options.json
restart: no
depends_on:
palantir:
condition: service_healthy
volumes:
- ./palantir-client:/local
# - ./options.json:/options.json

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="GetEFProjectMetadata">
<MSBuild Condition=" '$(TargetFramework)' == '' "
Projects="$(MSBuildProjectFile)"
Targets="GetEFProjectMetadata"
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0]);EFProjectMetadataFile=$(EFProjectMetadataFile)" />
<ItemGroup Condition=" '$(TargetFramework)' != '' ">
<EFProjectMetadata Include="AssemblyName: $(AssemblyName)" />
<EFProjectMetadata Include="Language: $(Language)" />
<EFProjectMetadata Include="OutputPath: $(OutputPath)" />
<EFProjectMetadata Include="Platform: $(Platform)" />
<EFProjectMetadata Include="PlatformTarget: $(PlatformTarget)" />
<EFProjectMetadata Include="ProjectAssetsFile: $(ProjectAssetsFile)" />
<EFProjectMetadata Include="ProjectDir: $(ProjectDir)" />
<EFProjectMetadata Include="RootNamespace: $(RootNamespace)" />
<EFProjectMetadata Include="RuntimeFrameworkVersion: $(RuntimeFrameworkVersion)" />
<EFProjectMetadata Include="TargetFileName: $(TargetFileName)" />
<EFProjectMetadata Include="TargetFrameworkMoniker: $(TargetFrameworkMoniker)" />
<EFProjectMetadata Include="Nullable: $(Nullable)" />
<EFProjectMetadata Include="TargetFramework: $(TargetFramework)" />
<EFProjectMetadata Include="TargetPlatformIdentifier: $(TargetPlatformIdentifier)" />
</ItemGroup>
<WriteLinesToFile Condition=" '$(TargetFramework)' != '' "
File="$(EFProjectMetadataFile)"
Lines="@(EFProjectMetadata)" />
</Target>
</Project>

View File

@ -0,0 +1,10 @@
@echo off
pushd "../../docker/code-gen"
rmdir /s /q "palantir-client"
rmdir /s /q "dotnet"
xcopy "../../src/dotnet" "./dotnet\" /E/H
cmd /c "docker-compose up --abort-on-container-exit --force-recreate"
cmd /c "docker-compose down"
rmdir /s /q "../../src/dotnet/Suspectus.Gandalf.Palantir.Client/Generated"
xcopy "./palantir-client" "../../src/dotnet/Suspectus.Gandalf.Palantir.Client/Generated\" /E/H
popd

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Gandalf" type="CompoundRunConfigurationType">
<toRun name="Suspectus.Gandalf.Bridgekeeper.Api: https" type="LaunchSettings" />
<toRun name="Suspectus.Gandalf.Palantir.Api: https" type="LaunchSettings" />
<method v="2" />
</configuration>
</component>

View File

@ -11,16 +11,34 @@ using Suspectus.Gandalf.Palantir.Data.Database.Repositories;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(TimeProvider.System); builder.Services.AddSingleton(TimeProvider.System);
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
var onlyControllers = args.Contains("--controllers-only");
if (onlyControllers)
{
builder.Services.AddOpenApi();
builder.Services.AddRouting(options => options.LowercaseUrls = true);
builder.Services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
var onlyControllersApp = builder.Build();
onlyControllersApp.MapOpenApi();
onlyControllersApp.UseHttpsRedirection();
onlyControllersApp.MapControllers();
onlyControllersApp.Run();
return;
}
builder.Services.AddDbContext<ApplicationContext>(cfg => cfg builder.Services.AddDbContext<ApplicationContext>(cfg => cfg
.UseNpgsql( .UseNpgsql(
builder.Configuration.GetConnectionString("DefaultConnection"), builder.Configuration.GetConnectionString("DefaultConnection"),
x => x.MigrationsAssembly("Suspectus.Gandalf.Palantir.Data") x => x.MigrationsAssembly("Suspectus.Gandalf.Palantir.Data")
) )
); );
builder.Services.AddAutoMapper(typeof(ApplicationContext).Assembly); builder.Services.AddAutoMapper(typeof(ApplicationContext).Assembly);
builder.Services.Configure<PasswordHasherOptions>(opt => builder.Services.Configure<PasswordHasherOptions>(opt =>

View File

@ -20,6 +20,17 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
},
"http-openapi-only": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5035",
"commandLineArgs": "--controllers-only",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
} }
} }
} }