Indiko.Hosting.Gateway
2.7.8
dotnet add package Indiko.Hosting.Gateway --version 2.7.8
NuGet\Install-Package Indiko.Hosting.Gateway -Version 2.7.8
<PackageReference Include="Indiko.Hosting.Gateway" Version="2.7.8" />
<PackageVersion Include="Indiko.Hosting.Gateway" Version="2.7.8" />
<PackageReference Include="Indiko.Hosting.Gateway" />
paket add Indiko.Hosting.Gateway --version 2.7.8
#r "nuget: Indiko.Hosting.Gateway, 2.7.8"
#:package Indiko.Hosting.Gateway@2.7.8
#addin nuget:?package=Indiko.Hosting.Gateway&version=2.7.8
#tool nuget:?package=Indiko.Hosting.Gateway&version=2.7.8
Indiko.Hosting.Gateway
A production-ready API Gateway hosting package built on Ocelot and HashiCorp Consul, with Indiko Blocks integration and a flexible host builder.
Features
- Ocelot API Gateway — route upstream requests to downstream microservices via JSON configuration
- Consul service discovery — automatic endpoint resolution for registered Consul services
- Forwarded headers — full
X-Forwarded-*support withKnownNetworksandKnownProxiescleared for trusted-proxy deployments ocelot.jsonauto-loading — the bootstrapper loadsocelot.jsonautomatically; no manual configuration setup required- Indiko Blocks — extend the gateway with auth, rate-limiting, tracing, or custom blocks participating in the full host lifecycle
- Flexible host builder —
ConfigureHostBuilder(...)fluent API for Windows Service, systemd, and custom configurations - Options-driven or property-override configuration — toggle features via
appsettings.jsonor subclass property overrides
Installation
dotnet add package Indiko.Hosting.Gateway
Quick Start
1. Create your Startup class
using Indiko.Hosting.Gateway;
public class Startup : GatewayStartup
{
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
: base(configuration, environment)
{
}
// Optional: add custom services before Ocelot runs
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services);
services.AddSingleton<IMyGatewayService, MyGatewayService>();
}
}
2. Write Program.cs
// Program.cs
return await new GatewayHostBootstrapper()
.RunAsync<Startup>(args);
3. Configure appsettings.json
{
"ServiceName": "MyGateway",
"Logging": {
"LogLevel": {
"Default": "Information",
"Ocelot": "Information"
}
},
"GatewayStartupOptions": {
"EnableForwardedHeaderOptions": true,
"ForceHttps": false
}
}
4. Create ocelot.json
Place ocelot.json in your project root. It is loaded automatically by GatewayHostBootstrapper.
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [{ "Host": "user-service", "Port": 80 }],
"UpstreamPathTemplate": "/users/{everything}",
"UpstreamHttpMethod": ["GET", "POST", "PUT", "DELETE"]
}
],
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "consul",
"Port": 8500,
"Type": "Consul"
}
}
}
5. Run
dotnet run
Configuration Approaches
Approach A: appsettings.json (recommended)
{
"GatewayStartupOptions": {
"EnableForwardedHeaderOptions": true,
"ForceHttps": false,
"AddControllersWithViews": false
}
}
All properties default to false when the section is absent.
Approach B: Property overrides in code
public class Startup : GatewayStartup
{
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
: base(configuration, environment)
{
}
protected override bool EnableForwardedHeaderOptions => true;
protected override bool ForceHttps => false;
protected override bool AddControllersWithViews => false;
}
Precedence: Subclass property overrides always win over
appsettings.jsonvalues.
Startup Options Reference
| Option | Type | Default | Used by base | Description |
|---|---|---|---|---|
EnableForwardedHeaderOptions |
bool |
false |
Yes | Enables UseForwardedHeaders with ForwardedHeaders.All, clearing KnownNetworks and KnownProxies |
ForceHttps |
bool |
false |
No (declared, available for subclasses) | Available for custom use in Configure overrides |
AddControllersWithViews |
bool |
false |
No (declared, available for subclasses) | Available for custom use in ConfigureServices overrides |
EnableForwardedHeaderOptions and ForceHttps are inherited from HostStartupOptions (defined in Indiko.Hosting.Abstractions). AddControllersWithViews is declared in GatewayStartupOptions for subclasses that need MVC controllers alongside the gateway.
Flexible Host Builder
Because GatewayHostBootstrapper is sealed, use the ConfigureHostBuilder fluent API:
// Windows Service
return await new GatewayHostBootstrapper()
.ConfigureHostBuilder(b => b.UseWindowsService())
.RunAsync<Startup>(args);
// systemd (Linux)
return await new GatewayHostBootstrapper()
.ConfigureHostBuilder(b => b.UseSystemd())
.RunAsync<Startup>(args);
// Custom Kestrel port
return await new GatewayHostBootstrapper()
.ConfigureHostBuilder(b => b.ConfigureWebHostDefaults(web =>
web.ConfigureKestrel(k => k.ListenAnyIP(8080))))
.RunAsync<Startup>(args);
// Chain multiple actions
return await new GatewayHostBootstrapper()
.ConfigureHostBuilder(b => b.UseWindowsService())
.ConfigureHostBuilder(b => b.ConfigureLogging(l => l.AddConsole()))
.RunAsync<Startup>(args);
ocelot.json
The GatewayHostBootstrapper calls config.AddJsonFile("ocelot.json") automatically during host construction. The file must exist in the application's working directory.
Basic route
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{ "Host": "user-service", "Port": 80 }
],
"UpstreamPathTemplate": "/users/{everything}",
"UpstreamHttpMethod": ["GET", "POST", "PUT", "DELETE"]
}
],
"GlobalConfiguration": {
"BaseUrl": "https://api.example.com"
}
}
With Consul service discovery and load balancing
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"ServiceName": "user-service",
"LoadBalancerOptions": { "Type": "RoundRobin" },
"UpstreamPathTemplate": "/users/{everything}",
"UpstreamHttpMethod": ["GET", "POST", "PUT", "DELETE"]
},
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"ServiceName": "order-service",
"LoadBalancerOptions": { "Type": "LeastConnection" },
"UpstreamPathTemplate": "/orders/{everything}",
"UpstreamHttpMethod": ["GET", "POST", "PUT", "DELETE"]
}
],
"GlobalConfiguration": {
"BaseUrl": "https://api.example.com",
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "consul",
"Port": 8500,
"Type": "Consul"
}
}
}
Consul Service Discovery
The bootstrapper calls services.AddOcelot(Configuration).AddConsul(), which registers the Consul service discovery provider. The provider is activated when GlobalConfiguration.ServiceDiscoveryProvider.Type is "Consul" in ocelot.json.
Routes use "ServiceName" instead of "DownstreamHostAndPorts" when discovery is active:
{
"ServiceName": "product-service",
"LoadBalancerOptions": { "Type": "RoundRobin" }
}
Consul resolves registered instances of product-service and the load balancer selects among them. Health-checked instances that fail are automatically removed.
Forwarded Headers
The Gateway package uses a stricter forwarded headers configuration than the BlazorServer package. When EnableForwardedHeaderOptions = true:
var options = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.All
};
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
app.UseForwardedHeaders(options);
KnownNetworks and KnownProxies are cleared so that forwarded headers from any upstream proxy are trusted. This is appropriate for gateway deployments behind an internal load balancer or Kubernetes ingress where the proxy IP is not fixed.
Do not enable this on internet-facing applications without a trusted proxy — it would allow clients to spoof their IP address via
X-Forwarded-For.
Extending with Indiko Blocks
Blocks hook into the gateway lifecycle at every stage:
| Hook | Called in |
|---|---|
ConfigureBuilder(IHostBuilder) |
CreateHostBuilder — before the host is built |
ConfigureServices(IServiceCollection) |
GatewayStartup.ConfigureServices — after Ocelot and Consul |
Configure(IApplicationBuilder, ...) |
GatewayStartup.Configure — between forwarded headers and UseOcelot |
PreRunAsync(IServiceProvider) |
BuildHost — after the host is built, before RunAsync |
Example: adding an authentication block and a rate-limiting block:
// The blocks register themselves via Indiko block discovery.
// In appsettings.json, reference the block assemblies:
{
"Blocks": [
"Indiko.Blocks.Security.Authentication.ASPNetCore",
"Indiko.Blocks.RateLimiting"
]
}
Best Practices
- Always set
EnableForwardedHeaderOptions = truewhen the gateway runs behind a Kubernetes ingress, nginx, or any other reverse proxy. - Use Consul service discovery with health checks rather than hardcoded
DownstreamHostAndPortsin production. - Set
ForceHttps = falsewhen TLS terminates at the ingress layer; enable it only when the gateway itself terminates TLS. - Separate
ocelot.jsonper environment using Ocelot's environment-specific file convention:ocelot.Development.json,ocelot.Production.json. Load them alongsideocelot.jsonin aConfigureHostBuilderaction. - Keep the
ConfigureServicesandConfigureoverrides minimal — delegate cross-cutting concerns (auth, rate limiting, tracing) to Indiko Blocks.
Target Framework
.NET 10
License
MIT — see LICENSE in the repository root.
Related Packages
| Package | Description |
|---|---|
Indiko.Hosting.Abstractions |
Core hosting abstractions and base bootstrapper |
Indiko.Hosting.BlazorServer |
Blazor Server hosting with OIDC |
Indiko.Blocks.Communication.ServiceToService.Consul |
Service-to-service communication via Consul |
Indiko.Blocks.Tracing.OpenTelemetry |
Distributed tracing for the gateway |
Indiko.Blocks.Logging.Serilog |
Structured logging block |
Resources
| 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
- Indiko.Hosting.Abstractions (>= 2.7.8)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 10.0.6)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.6)
- Microsoft.Extensions.DependencyModel (>= 10.0.6)
- Ocelot (>= 24.1.0)
- Ocelot.Provider.Consul (>= 24.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.7.8 | 86 | 5/7/2026 |
| 2.7.7 | 87 | 5/7/2026 |
| 2.7.6 | 98 | 4/23/2026 |
| 2.7.5 | 94 | 4/23/2026 |
| 2.7.4 | 105 | 4/23/2026 |
| 2.7.3 | 92 | 4/23/2026 |
| 2.7.2 | 96 | 4/23/2026 |
| 2.7.1 | 89 | 4/23/2026 |
| 2.7.0 | 90 | 4/23/2026 |
| 2.6.4 | 98 | 4/21/2026 |
| 2.6.3 | 93 | 4/21/2026 |
| 2.6.2 | 91 | 4/21/2026 |
| 2.6.1 | 100 | 4/18/2026 |
| 2.6.0 | 100 | 4/17/2026 |
| 2.5.1 | 92 | 4/14/2026 |
| 2.5.0 | 116 | 3/30/2026 |
| 2.2.18 | 106 | 3/8/2026 |
| 2.2.17 | 101 | 3/8/2026 |
| 2.2.16 | 98 | 3/8/2026 |
| 2.2.15 | 98 | 3/7/2026 |