Fast, flexible, and easy to extend
- Reverse Proxy
- Load Balancing
- Rate Limiting
- Health Check
- Service Discovery
There are three ways to configure the api gateway
- Use json to configure the target server address
- lib
Meloht.API.Gateway.Json
- lib
- Use database to configure the target server address
- MySql database provider lib
Meloht.API.Gateway.MySql - SQL Server database provider lib
Meloht.API.Gateway.SqlServer - PostgreSQL database provider lib
Meloht.API.Gateway.PostgreSQL
- MySql database provider lib
- Use Service Discovery to configure the target server address
- MySql database provider lib
Meloht.API.ServiceDiscovery.Provider.MySql - SQL Server database provider lib
Meloht.API.ServiceDiscovery.Provider.SqlServer - PostgreSQL database provider lib
Meloht.API.ServiceDiscovery.Provider.PostgreSQL
- MySql database provider lib
The weight of the target server can be configured
- FirstAlphabetical Select the alphabetically first available destination without considering load. This is useful for dual destination fail-over systems.
- Random Select a destination randomly.
- RoundRobin Select a destination by cycling through them in order.
- LeastRequests Select the destination with the least assigned requests. This requires examining all destinations.
- PowerOfTwoChoices Select two random destinations and then select the one with the least assigned requests. This avoids the overhead of LeastRequests and the worst case for Random where it selects a busy destination.
Use appsetting.json to configure the target server address, using the lib Meloht.API.Gateway.Json

using Meloht.API.Gateway.Json;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddOpenApi();
builder.Services.AddGatewayService(builder.Configuration);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseGateway();
app.MapControllers();
app.Run();appsetting.json
"Gateway": {
"LoadBalancingPolicy": "RoundRobin",
"ReverseProxy": {
"RequestQueuePoolSize": 1000,
"RequestTimeoutSeconds": 120
},
"HealthCheck": {
"IntervalSeconds": 10,
"RequestTimeoutSeconds": 5
},
"ServiceDiscovery": {
"IntervalSeconds": 10,
"RequestTimeoutSeconds": 5,
"ServiceDiscoveryHost": "https://localhost:5500"
},
"TargetServers": [
{
"Id": 1,
"UniqueName": "test01",
"Host": "localhost:8081",
"Protocol": "http",
"Weight": 1
}
]
},
using Meloht.API.Gateway.MySql;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddOpenApi();
builder.Services.AddGatewayService(builder.Configuration);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseGateway();
app.MapControllers();
app.Run();appsettings.json
"Gateway": {
"LoadBalancingPolicy": "RoundRobin",
"ReverseProxy": {
"RequestQueuePoolSize": 1000,
"RequestTimeoutSeconds": 120
},
"DatabaseAutoUpdate": {
"IntervalSeconds": 120,
"DatabaseTimeoutSeconds": 5,
"ConnectionString": "Server=127.0.0.1;Port=3306;Database=testdb;User ID=root;Password=123456;"
},
"HealthCheck": {
"IntervalSeconds": 10,
"RequestTimeoutSeconds": 5
},
}
using Meloht.API.Gateway.ServiceDiscovery;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddOpenApi();
builder.Services.AddGatewayService(builder.Configuration);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseGateway();
app.MapControllers();
app.Run();appsettings.json
"Gateway": {
"LoadBalancingPolicy": "RoundRobin",
"ReverseProxy": {
"RequestQueuePoolSize": 1000,
"RequestTimeoutSeconds": 120
}
}
using Meloht.API.Gateway.Client;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddClientServiceDiscovery(builder.Configuration);
var app = builder.Build();
app.UseGatewayClient();appsettings.json
"GatewayClient": {
"ClientProtocol": "http",
"ClientUniqueName": "test01",
"ClientWeight": 1,
"ServiceDiscoveryProtocol": "http",
"ServiceDiscoveryHost": "localhost:5500",
"RequestTimeoutSeconds": 5
}using Meloht.API.ServiceDiscovery.Provider.MySql;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddServiceDiscovery(builder.Configuration);
var app = builder.Build();
app.UseServiceDiscovery();appsettings.json
"ServiceDiscovery": {
"DatabaseConfig": {
"IntervalSeconds": 60,
"DatabaseTimeoutSeconds": 5,
"ConnectionString": null
},
"HealthCheck": {
"IntervalSeconds": 10,
"RequestTimeoutSeconds": 5
}
}Ten thousand concurrent request test
| PC | System | CPU | RAM | Storage | Summary |
|---|---|---|---|---|---|
| PC1 | Windows 10 Pro 22H2 | AMD Ryzen 7 5800X 8-Core Processor 3.8GHz | DDR4 3200 MHz 32GB | SSD 2TB | JMeter & Service Endpoint 1 |
| PC2 | Windows 10 Pro 22H2 | i7-10510U 2.3GHz | DDR4 2667 MHz 16GB | SSD 2TB | Service Endpoint 2 |
| PC3 | Windows 10 Pro 22H2 | i7-4500U 2.4GHz | DDR3 1600 MHz 8GB | HDD 1TB | Service Endpoint 3 |
"Gateway": {
"LoadBalancingPolicy": "RoundRobin",
"ReverseProxy": {
"RequestQueuePoolSize": 1000,
"RequestTimeoutSeconds": 120
},
"HealthCheck": {
"IntervalSeconds": 10,
"RequestTimeoutSeconds": 5
},
"TargetServers": [
{
"Id": 1,
"UniqueName": "test01",
"Host": "192.168.3.7:8081",
"Protocol": "http",
"Weight": 1
},
{
"Id": 2,
"UniqueName": "test02",
"Host": "192.168.3.26:8081",
"Protocol": "http",
"Weight": 1
},
{
"Id": 3,
"UniqueName": "test03",
"Host": "192.168.3.7:8082",
"Protocol": "http",
"Weight": 1
},
{
"Id": 4,
"UniqueName": "test04",
"Host": "192.168.3.7:8083",
"Protocol": "http",
"Weight": 1
},
{
"Id": 5,
"UniqueName": "test05",
"Host": "192.168.3.26:8082",
"Protocol": "http",
"Weight": 1
},
{
"Id": 6,
"UniqueName": "test06",
"Host": "192.168.3.7:8084",
"Protocol": "http",
"Weight": 1
},
{
"Id": 7,
"UniqueName": "test07",
"Host": "192.168.3.7:8085",
"Protocol": "http",
"Weight": 1
},
{
"Id": 8,
"UniqueName": "test08",
"Host": "localhost:8081",
"Protocol": "http",
"Weight": 1
}
]
}