SaveApis.Framework

Documentation for SaveApis.Framework

View on GitHub

Web Framework

SaveApis.Framework.Web provides a ready-to-use ASP.NET Core application with structured logging, OpenTelemetry, FluentValidation, authentication/authorization via Zitadel, controller routing, and an OpenAPI/Scalar UI — all wired up through the Installer system.


Table of Contents


Overview

When to use: Use the Web Framework whenever you are building an HTTP API or web service.

What it provides out of the box:

Key difference from other frameworks: The Web Framework uses WebApplicationBuilder / WebApplication internally and is the only framework that supports HTTP middleware pipeline configuration via ConfigureApplication.


Entry Point

Start the application from Program.cs:

using SaveApis.Framework;
using SaveApis.Framework.Web.Extensions;

await SaveApisApplication
    .AsWeb(
        args,
        (app, installer) =>
        {
            app.Name = "My.Service";
            app.Namespace = "My.Org";

            installer.SetSoftwareAssembly(); // required for controller and validator scanning
        }
    )
    .Build()
    .RunAsync()
    .ConfigureAwait(false);

The configure callback receives an ApplicationContext (app) and a WebInstallerContext (installer). Both are optional — the callback itself can be omitted.

Add your own installers before Build():

await SaveApisApplication
    .AsWeb(args, (app, installer) => { ... })
    .AddInstaller<MyInstaller>()
    .Build()
    .RunAsync();

Default Installers

The following installers are registered automatically when you call AsWeb(). They run in dependency order:

# Installer Key Default Enabled
1 LoggingInstaller Logging
2 OpenTelemetryInstaller OpenTelemetry
3 ValidationInstaller Validation
4 AuthenticationInstaller Authentication
5 AuthorizationInstaller Authorization
6 ZitadelInstaller Zitadel
7 ControllerInstaller Controller
8 OpenApiInstaller OpenApi
9 ScalarInstaller Scalar

LoggingInstaller

Key: Logging

Clears all default logging providers and installs Serilog with a formatted ANSI console sink.

Default minimum level: Information

Built-in overrides (always applied):

Configuration (section Logging):

Key Type Default Description
Logging:Default LogEventLevel Information Global minimum log level
Logging:Override:<source> LogEventLevel Per-source override, e.g. Logging:Override:MyNamespace

Example (appsettings.json):

{
  "Logging": {
    "Default": "Debug",
    "Override": {
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

OpenTelemetryInstaller

Key: OpenTelemetry

Registers OpenTelemetry SDK with logging, metrics, and tracing exported via OTLP. The resource is configured with SaveApisApplication.Name, SaveApisApplication.Namespace, and Environment.MachineName.

Instrumentation included:

Configuration (section OpenTelemetry):

Key Type Default Description
OpenTelemetry:Endpoint Uri (required) OTLP exporter endpoint
OpenTelemetry:Protocol OtlpExportProtocol Grpc Grpc or HttpProtobuf
OpenTelemetry:Logging:Enabled bool true Enable log export
OpenTelemetry:Metrics:Enabled bool true Enable metrics export
OpenTelemetry:Tracing:Enabled bool true Enable trace export
OpenTelemetry:Tracing:IgnoredPaths string[] ["/scalar", "/openapi"] Paths excluded from tracing

ValidationInstaller

Key: Validation

Scans SoftwareAssembly and all additional assemblies from InstallerContext.Assemblies for FluentValidation IValidator<T> implementations and registers them in the DI container.

No configuration required.


AuthenticationInstaller

Key: Authentication

Registers ASP.NET Core Authentication services (builder.Services.AddAuthentication()) and adds the UseAuthentication() middleware to the pipeline.

This installer must run before AuthorizationInstaller, ZitadelInstaller, ControllerInstaller, OpenApiInstaller, and ScalarInstaller — all declared as Before dependencies.

No configuration required on its own; configure authentication schemes in additional installers (e.g. ZitadelInstaller).


AuthorizationInstaller

Key: Authorization

Registers ASP.NET Core Authorization services (builder.Services.AddAuthorization()) and adds the UseAuthorization() middleware.

Must run after AuthenticationInstaller and before ZitadelInstaller, ControllerInstaller, OpenApiInstaller, and ScalarInstaller.

No configuration required.


ZitadelInstaller

Key: Zitadel

Adds Zitadel token introspection as an authentication scheme. Only activates if Zitadel:JwtProfile is set — if the value is empty or missing, the installer is a no-op (no error).

Also registers a distributed memory cache used by the introspection middleware for caching tokens for 5 minutes.

Must run after AuthenticationInstaller and AuthorizationInstaller.

Configuration (section Zitadel):

Key Type Required Description
Zitadel:Authority Uri Yes Zitadel instance URL (e.g. https://auth.example.com/)
Zitadel:JwtProfile string Yes JSON string of the Zitadel service account JWT profile
Zitadel:Scopes Dictionary<string, string> No OAuth2 scopes shown in Scalar/OpenAPI UI

Default scopes (used by OpenApiInstaller for the security scheme):

{
  "openid": "OpenID Connect",
  "profile": "Profile",
  "email": "Email",
  "urn:zitadel:iam:user:resourceowner": "Organization Name"
}

Tip: To disable Zitadel in development, use installer.WithZitadel(false) in the configure callback. The OpenApiInstaller and ScalarInstaller will automatically omit the security scheme.


ControllerInstaller

Key: Controller

Registers ASP.NET Core MVC controllers, adds all controller application parts from SoftwareAssembly and InstallerContext.Assemblies, configures JsonStringEnumConverter for all JSON serialization, and maps controllers with .RequireAuthorization() in the pipeline.

Must run after AuthenticationInstaller, AuthorizationInstaller, and ZitadelInstaller.

No configuration required.


OpenApiInstaller

Key: OpenApi

Generates an OpenAPI document using the built-in ASP.NET Core OpenAPI support and exposes it at /openapi/v1.json (anonymous access).

When Zitadel is enabled, automatically adds an OAuth2 Authorization Code security scheme to the document using the Zitadel:Authority and Zitadel:Scopes configuration values.

Must run after ControllerInstaller.

No additional configuration required.


ScalarInstaller

Key: Scalar

Mounts the Scalar API Reference UI (anonymous access). Configured with opinionated defaults:

Must run after OpenApiInstaller.

No configuration required.


Custom Installers

Inherit from BaseWebInstaller to create your own installer:

public class MyInstaller : BaseWebInstaller
{
    public override string InstallerKey => "My";

    // Optional: declare ordering constraints
    public override IReadOnlyCollection<InstallerDependency> Dependencies =>
    [
        InstallerDependency.After<ValidationInstaller>(),
    ];

    public override void ConfigureBuilder(
        SaveApisWebApplicationBuilder builder,
        WebInstallerContext context)
    {
        builder.Services.AddScoped<IMyService, MyService>();
    }

    public override void ConfigureApplication(
        SaveApisWebApplication application,
        WebInstallerContext context)
    {
        application.Use(app => app.UseMyMiddleware());
    }
}

Register it in Program.cs:

await SaveApisApplication
    .AsWeb(args, (app, installer) => { ... })
    .AddInstaller<MyInstaller>()
    .Build()
    .RunAsync();

Reading configuration options:

public override void ConfigureBuilder(SaveApisWebApplicationBuilder builder, WebInstallerContext context)
{
    var options = GetOption<MyOptions>(builder); // reads section "My" (= InstallerKey)
    builder.Services.AddSingleton(options);
}

For the full installer API (lifecycle, dependencies, ShouldInstall, etc.) see the Base Framework documentation.


Enabling & Disabling Installers

Use the WebInstallerContext extension methods in the configure callback:

(app, installer) =>
{
    installer.WithLogging(false);          // disable Serilog
    installer.WithOpenTelemetry(false);    // disable OpenTelemetry
    installer.WithValidation(false);       // disable FluentValidation
    installer.WithAuthentication(false);   // disable Authentication middleware
    installer.WithAuthorization(false);    // disable Authorization middleware
    installer.WithZitadel(false);          // disable Zitadel introspection
    installer.WithControllers(false);      // disable controller registration
    installer.WithOpenApi(false);          // disable OpenAPI document
    installer.WithScalar(false);           // disable Scalar UI
}

All methods default to true (enable) and accept false to disable.


Configuration Reference

Section Key Type Default Required
Logging Default LogEventLevel Information No
Logging Override:<source> LogEventLevel No
OpenTelemetry Endpoint Uri Yes (if enabled)
OpenTelemetry Protocol OtlpExportProtocol Grpc No
OpenTelemetry Logging:Enabled bool true No
OpenTelemetry Metrics:Enabled bool true No
OpenTelemetry Tracing:Enabled bool true No
OpenTelemetry Tracing:IgnoredPaths string[] ["/scalar","/openapi"] No
Zitadel Authority Uri Yes (if enabled)
Zitadel JwtProfile string Yes (if enabled)
Zitadel Scopes Dictionary<string,string> (see above) No

Installer Sub-Pages

Detailed documentation for each default installer, including full configuration reference (appsettings + environment variables) and context extension methods:

Installer Sub-Page
LoggingInstaller logging/
OpenTelemetryInstaller opentelemetry/
ValidationInstaller validation/
AuthenticationInstaller authentication/
AuthorizationInstaller authorization/
ZitadelInstaller zitadel/
ControllerInstaller controller/
OpenApiInstaller openapi/
ScalarInstaller scalar/