Headless.Api.ServiceDefaults
0.4.15
dotnet add package Headless.Api.ServiceDefaults --version 0.4.15
NuGet\Install-Package Headless.Api.ServiceDefaults -Version 0.4.15
<PackageReference Include="Headless.Api.ServiceDefaults" Version="0.4.15" />
<PackageVersion Include="Headless.Api.ServiceDefaults" Version="0.4.15" />
<PackageReference Include="Headless.Api.ServiceDefaults" />
paket add Headless.Api.ServiceDefaults --version 0.4.15
#r "nuget: Headless.Api.ServiceDefaults, 0.4.15"
#:package Headless.Api.ServiceDefaults@0.4.15
#addin nuget:?package=Headless.Api.ServiceDefaults&version=0.4.15
#tool nuget:?package=Headless.Api.ServiceDefaults&version=0.4.15
Headless.Api.ServiceDefaults
The one-line bootstrap for Headless APIs. Combines the Headless.Api.Core primitives with Aspire-style host conventions: OpenTelemetry, OpenAPI document mapping, service discovery, HttpClient resilience, and startup validation.
If you want the happy-path API bootstrap, install this package. It transitively pulls in Headless.Api.Core.
Installation
dotnet add package Headless.Api.ServiceDefaults
Quick Start
var builder = WebApplication.CreateBuilder(args);
ApiSetup.ConfigureGlobalSettings();
builder.AddHeadless();
var app = builder.Build();
app.UseHeadless();
app.MapHeadlessEndpoints();
app.Run();
That's the whole minimal setup. AddHeadless() registers all core primitives plus the Aspire-style conventions. UseHeadless() applies the default middleware order. MapHeadlessEndpoints() maps /health, /alive, OpenAPI JSON, and static web assets.
Configuration
builder.AddHeadless(configureServices: options =>
{
options.Validation.ValidateServiceProviderOnStartup = true;
options.Validation.RequireUseHeadless = true;
options.Validation.RequireMapHeadlessEndpoints = true;
options.OpenTelemetry.Enabled = true;
options.OpenTelemetry.UseOtlpExporterWhenEndpointConfigured = true;
options.OpenTelemetry.ConfigureMetrics = metrics => metrics.AddMeter("MyApp.*");
options.OpenApi.Enabled = true;
options.OpenApi.RoutePattern = "/openapi/{documentName}.json";
options.OpenApi.CacheDocument = true;
options.HttpClient.UseServiceDiscovery = true;
options.HttpClient.UseStandardResilienceHandler = true;
options.HttpClient.AddApplicationUserAgent = true;
options.StaticAssets.Enabled = true;
});
AddHeadless() also accepts overloads for explicit string-encryption and string-hash configuration:
AddHeadless(IConfiguration stringEncryptionConfig, IConfiguration stringHashConfig, ...)AddHeadless(Action<StringEncryptionOptions>, Action<StringHashOptions>?, ...)AddHeadless(Action<StringEncryptionOptions, IServiceProvider>, Action<StringHashOptions, IServiceProvider>?, ...)
Without those overloads, AddHeadless() binds Headless:StringEncryption and Headless:StringHash sections from IConfiguration by default.
What's Registered
AddHeadless() performs the following:
- Service-provider validation on startup (
ValidateOnBuild,ValidateScopes) - All core primitives from
Headless.Api.Core(problem details, response compression, JWT, identity, status codes rewriter, default API conventions). Antiforgery service registration is opt-in viaoptions.Antiforgery.Enabled(cookie-auth apps only). - MVC and Minimal API JSON serializer defaults
- ASP.NET Core source-generated input validation (
services.AddValidation()) - OpenTelemetry logging, metrics, and tracing (when
OpenTelemetry.Enabled) - OpenAPI service registration (when
OpenApi.Enabled) - Service discovery (when
HttpClient.UseServiceDiscovery) - HttpClient defaults — standard resilience handler, service discovery, application User-Agent
- Startup filter that validates
UseHeadless()andMapHeadlessEndpoints()were called
Pipeline & Endpoints
UseHeadless() applies the default middleware order:
UseForwardedHeaders()UseResponseCompression()UseStatusCodePages()+UseStatusCodesRewriter()(rewrites bare 401/403/404 into ProblemDetails)UseExceptionHandler()UseHttpsRedirection()UseHsts()outside Development- no-cache response header when the response did not set
Cache-Control
Antiforgery is consumer-owned and opt-in. By default AddHeadless() does not register the antiforgery service and UseHeadless() does not wire the middleware — CSRF protection is meaningful only for cookie-based authentication, and most "headless" APIs use bearer tokens / API keys where there is no CSRF surface. Cookie-auth consumers explicitly opt in and wire the middleware after UseAuthentication()/UseAuthorization():
builder.AddHeadless(configureServices: options =>
{
options.Antiforgery.Enabled = true;
});
// ...
app.UseHeadless();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
MapHeadlessEndpoints() maps:
/health— aggregate health endpoint (JSON body withstatusand per-checkresults)/alive— liveness endpoint (checks taggedlive)- OpenAPI JSON document at the configured route pattern (when
OpenApi.Enabled) - Static web assets when their manifest exists (when
StaticAssets.Enabled)
All operational endpoints are named, excluded from OpenAPI descriptions, and allow anonymous requests by default. Both UseHeadless and MapHeadlessEndpoints are idempotent.
Multi-Tenancy
AddHeadless() does not enable HTTP tenant resolution by default. Add tenancy explicitly:
builder.AddHeadlessTenancy(tenancy => tenancy.Http(http => http.ResolveFromClaims()));
var app = builder.Build();
app.UseHeadless();
app.UseAuthentication();
app.UseHeadlessTenancy(); // between auth and authz
app.UseAuthorization();
app.MapHeadlessEndpoints();
// Cookie-auth apps that opted into `options.Antiforgery.Enabled` should also
// call `app.UseAntiforgery()` here, after authorization. See the Antiforgery
// section above. Bearer-token APIs leave it out.
Startup Validation
By default, the runtime validates that UseHeadless() and MapHeadlessEndpoints() were called before the host starts. This catches forgotten middleware/endpoint wiring in deployment. Disable per environment if you build a custom pipeline:
builder.AddHeadless(configureServices: options =>
{
options.Validation.RequireUseHeadless = false;
options.Validation.RequireMapHeadlessEndpoints = false;
});
Configuration Sections
String Encryption
{
"Headless": {
"StringEncryption": {
"DefaultPassPhrase": "YourPassPhrase123",
"InitVectorBytes": "WW91ckluaXRWZWN0b3IxNg==",
"DefaultSalt": "WW91clNhbHQ="
}
}
}
String Hashing
{
"Headless": {
"StringHash": {
"Iterations": 600000,
"Size": 128,
"Algorithm": "SHA256",
"DefaultSalt": "DefaultSalt"
}
}
}
Both sections are required.
Dependencies
Headless.Api.Core(transitive: brings all core primitives)Microsoft.AspNetCore.OpenApiMicrosoft.Extensions.Http.ResilienceMicrosoft.Extensions.ServiceDiscoveryOpenTelemetry.Exporter.OpenTelemetryProtocolOpenTelemetry.Extensions.HostingOpenTelemetry.Instrumentation.AspNetCoreOpenTelemetry.Instrumentation.HttpOpenTelemetry.Instrumentation.Runtime
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Asp.Versioning.Abstractions (>= 10.0.0)
- Asp.Versioning.Http (>= 10.0.0)
- CommunityToolkit.HighPerformance (>= 8.4.2)
- DeviceDetector.NET (>= 6.5.0)
- FileSignatures (>= 7.2.0)
- FluentValidation (>= 12.1.1)
- FluentValidation.DependencyInjectionExtensions (>= 12.1.1)
- Headless.Api.Core (>= 0.4.15)
- Humanizer.Core (>= 3.0.10)
- IdGen (>= 3.0.7)
- JetBrains.Annotations (>= 2025.2.4)
- libphonenumber-csharp (>= 9.0.30)
- Microsoft.AspNetCore.MiddlewareAnalysis (>= 10.0.8)
- Microsoft.AspNetCore.OpenApi (>= 10.0.8)
- Microsoft.Bcl.TimeProvider (>= 10.0.8)
- Microsoft.Extensions.DiagnosticAdapter (>= 3.1.32)
- Microsoft.Extensions.Http.Resilience (>= 10.6.0)
- Microsoft.Extensions.ServiceDiscovery (>= 10.6.0)
- Microsoft.Extensions.Telemetry.Abstractions (>= 10.6.0)
- Microsoft.IdentityModel.JsonWebTokens (>= 8.18.0)
- Microsoft.OpenApi (>= 2.4.1)
- morelinq (>= 4.4.0)
- NetEscapades.AspNetCore.SecurityHeaders (>= 1.3.1)
- Nito.AsyncEx (>= 5.1.2)
- Nito.Disposables (>= 2.5.0)
- OpenMcdf (>= 3.1.3)
- OpenTelemetry (>= 1.15.3)
- OpenTelemetry.Api (>= 1.15.3)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.15.3)
- OpenTelemetry.Extensions.Hosting (>= 1.15.3)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.15.2)
- OpenTelemetry.Instrumentation.Http (>= 1.15.1)
- OpenTelemetry.Instrumentation.Runtime (>= 1.15.1)
- Polly.Core (>= 8.6.6)
- Polly.Extensions (>= 8.6.4)
- Polly.RateLimiting (>= 8.6.4)
- Scrutor (>= 7.0.0)
- Snappier (>= 1.3.1)
- System.Reactive (>= 6.1.0)
- TimeZoneConverter (>= 7.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.