---
title: Hosting pipeline
summary: Host model, server, ordered middleware pipeline, API versioning, OpenAPI exposure, health checks, and telemetry.
status: draft
owner: Premium Systems Team
last_reviewed: 2026-10-21
---

# Hosting pipeline

`SAIF.Premium.Api` is an ASP.NET Core 8 Web API hosted in-process by IIS through
the ASP.NET Core Module V2. `Program.cs` uses the minimal host
(`WebApplication.CreateBuilder`) but hands service and middleware configuration
to a `Startup` type derived from the SAIF `CoreAPIStartup` base class, so the
pipeline is a mix of calls the repository makes and contributions the base class
makes that source does not show. A request passes the base class's opaque
`ConfigureMiddleware` step, Swagger, and the base class's opaque `Configure`
step before it reaches a controller action or the one minimal API group. API
versioning is read from the URL segment, so `v1` and `v2` are part of the route.

## Host model

| Field | Value |
| --- | --- |
| **Entry point** | `src/SAIF.Premium.Api/Program.cs` |
| **Host builder** | Minimal host - `WebApplication.CreateBuilder(args)` driving a `Startup` instance by hand |
| **Startup call chain** | `new Startup(builder.Configuration)` -> `startup.ConfigureServices(builder.Services)` -> `builder.Build()` -> `startup.ConfigureMiddleware(app)` -> `startup.Configure(app, app.Environment)` -> `app.MapGroup("/v1/RateTables").MapRateTableEndpoints()` -> `app.Run()` |
| **Host-builder extensions** | `builder.Host.ConfigureOpenTelemetry(o => o.Owner = "Premium Systems Team")` |
| **Startup type** | `Startup` (`src/SAIF.Premium.Api/Startup.cs`) |
| **Base class** | `CoreAPIStartup` (`SAIF.NetCore.ServiceExtensions` `8.2.1`) |
| **Target framework** | `net8.0` |

The repository uses both host styles: the host is a minimal host, and
`Program.cs` calls the `Startup` methods itself rather than through
`UseStartup<Startup>()`. `Startup.ConfigureServices` calls
`base.ConfigureServices(services)` as its first statement, before any local
registration. `Startup` declares no `ConfigureMiddleware` method;
`startup.ConfigureMiddleware(app)` resolves to a method that exists only on
`CoreAPIStartup`, so what it registers is not visible in source.

### Base-class flags

| Flag or call | Value | Set in | Effect (as far as source shows) |
| --- | --- | --- | --- |
| `EnableSecureEnvironmentClient<Startup>()` | Called | `src/SAIF.Premium.Api/Startup.cs:22` | Enables the secure `IEnvironmentClient`, which decrypts secure settings; the registration itself is opaque, contributed by `SAIF.NetCore.ServiceExtensions`† |
| `EnableNewtonsoftJsonSerializer` | Not set | - | The base class's default serializer stays in effect† |
| `DisableAuthServices` | Not set | - | The base class's authentication and authorization services stay registered; their configuration is opaque† |
| `WebHostEnvironment.EnvironmentName` | `Configuration["AppSettings:ApplicationHost"]` | `src/SAIF.Premium.Api/Startup.cs:23` | The environment name comes from `appsettings.json`, not from `ASPNETCORE_ENVIRONMENT` |

## Server

| Aspect | Finding |
| --- | --- |
| Server | IIS in-process (ASP.NET Core Module V2) |
| Hosting model evidence | `web.config` `<aspNetCore ... hostingModel="InProcess">` and `<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>` in `src/SAIF.Premium.Api/SAIF.Premium.Api.csproj` |
| `web.config` notes | The checked-in `arguments` value still references `bin\Debug\net6.0\SAIF.Premium.Api.dll` while the target framework is `net8.0`; recorded in Tech debt |
| Local launch profiles | `Properties\launchSettings.json` - profiles `SAIF.Premium.Api` (`Project`) and `IIS Express`, both with `launchUrl` = `swagger` (local development only) |

## Middleware pipeline

| Order | Middleware | Registered in | Condition | Status | Notes |
| --- | --- | --- | --- | --- | --- |
| 1 | `startup.ConfigureMiddleware(app)` | `src/SAIF.Premium.Api/Program.cs:19` | Always | Opaque | Declared only on `CoreAPIStartup` (`SAIF.NetCore.ServiceExtensions`)† - not visible in source; runs before `Startup.Configure` |
| 2 | `app.UseHttpsRedirection()` | `src/SAIF.Premium.Api/Startup.cs:50` | - | Commented out | Disabled in source, so this service applies no HTTPS redirection of its own |
| 3 | `app.UseSwagger()` | `src/SAIF.Premium.Api/Startup.cs:51` | Always | Active | Not gated by environment; the OpenAPI documents are served on every track |
| 4 | `app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Premium API v1"); c.SwaggerEndpoint("/swagger/v2/swagger.json", "Premium API v2"); })` | `src/SAIF.Premium.Api/Startup.cs:52` | Always | Active | One endpoint per declared API version |
| 5 | `base.Configure(app, env)` | `src/SAIF.Premium.Api/Startup.cs:57` | Always | Opaque | Contributed by `CoreAPIStartup` (`SAIF.NetCore.ServiceExtensions`)† - not visible in source. Controller endpoint mapping happens inside this call; the relative order of routing, authentication and authorization is not visible in source |
| 6 | `app.MapGroup("/v1/RateTables").MapRateTableEndpoints()` | `src/SAIF.Premium.Api/Program.cs:22` | Always | Active | Minimal API group, registered after the `Startup` pipeline completes; see [Endpoints](endpoints.md) |

```mermaid
flowchart LR
    REQ["Request"] --> SRV["IIS in-process<br/>ASP.NET Core Module V2"]
    SRV --> CM["startup.ConfigureMiddleware<br/>opaque"]
    CM --> SW["app.UseSwagger"]
    SW --> SUI["app.UseSwaggerUI"]
    SUI --> BASE["base.Configure<br/>opaque"]
    BASE --> CTRL["Controller action"]
    BASE --> MIN["Minimal API endpoint<br/>MapGroup /v1/RateTables"]
```

`app.UseHttpsRedirection()` is not drawn: it is commented out and does not run.

## API versioning

| Aspect | Finding |
| --- | --- |
| Package | `Asp.Versioning.Mvc` `8.1.0` and `Asp.Versioning.Mvc.ApiExplorer` `8.1.0` |
| Registration | `services.AddApiVersioning(...)` in `src/SAIF.Premium.Api/Startup.cs:33` |
| Default version | `1.0` |
| Assume default when unspecified | Yes |
| Report API versions | Yes |
| Version reader | `UrlSegmentApiVersionReader` |
| Versioned API explorer | `AddApiExplorer` - `GroupNameFormat = "'v'VVV"`, `SubstituteApiVersionInUrl = true` |
| Versions declared | `[ApiVersion("1.0")]` on `PremiumsController`; `[ApiVersion("1.0")]` and `[ApiVersion("2.0")]` on `ClassCodesController`; `AdminController` and the `RateTableEndpoints` group declare no version and use a literal `v1` route prefix |

## API documentation surface

| Aspect | Finding |
| --- | --- |
| Generator | Swashbuckle `AddSwaggerGen` |
| State | Active |
| Document(s) | `v1` and `v2`, one `SwaggerDoc` per declared API version |
| Exposed route | `swagger/v1/swagger.json` and `swagger/v2/swagger.json`, with Swagger UI at `swagger` |
| XML comments | `IncludeXmlComments("SAIF.Premium.Api.xml")` with `<GenerateDocumentationFile>true</GenerateDocumentationFile>` |
| Security definitions | None |
| Operation filters | None |
| Package and version | `Swashbuckle.AspNetCore` `6.5.0` |

## Health checks

| Aspect | Finding |
| --- | --- |
| ASP.NET Core health checks | None found |
| SAIF pingable registrations | `AddPingableTransient<IPremiumRepository, PremiumRepository>()` in `src/SAIF.Premium.Api/Startup.cs:41` |
| Ping endpoint | Not determined from source |

## Telemetry

| Aspect | Finding |
| --- | --- |
| OpenTelemetry | `.ConfigureOpenTelemetry(o => o.Owner = "Premium Systems Team")` on the host builder |
| Application Insights | None found |
| Logging configuration | `appsettings.json` `Logging:LogLevel` - `Default` = `Information`, `Microsoft.AspNetCore` = `Warning` |
| Registered in | `src/SAIF.Premium.Api/Program.cs:14` |

## Related documentation
- API index
- Overview
- Architecture
- [Endpoints](endpoints.md)
- Authentication and authorization
- Dependencies
- [Configuration](configuration.md)
- Operations and processes
- Business rules
- Data model
- Operational runbook
- Tech debt

> **Note:** Statements marked with † were retrieved from dependency library documentation
> via the Legends CLI RAG service. They describe inherited behavior from the indicated
> origin library and should be verified if the dependency version changes.

## Sources
- `src/SAIF.Premium.Api/Program.cs`
- `src/SAIF.Premium.Api/Startup.cs`
- `src/SAIF.Premium.Api/SAIF.Premium.Api.csproj`
- `src/SAIF.Premium.Api/web.config`
- `src/SAIF.Premium.Api/Properties/launchSettings.json`
- `src/SAIF.Premium.Api/appsettings.json`
- `src/SAIF.Premium.Api/Controllers/PremiumsController.cs`
- `src/SAIF.Premium.Api/Controllers/ClassCodesController.cs`
- `src/SAIF.Premium.Api/Controllers/AdminController.cs`
- `src/SAIF.Premium.Api/Endpoints/RateTableEndpoints.cs`
