-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
111 lines (95 loc) · 3.11 KB
/
Copy pathProgram.cs
File metadata and controls
111 lines (95 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using Replane;
var builder = WebApplication.CreateBuilder(args);
// Create and configure the Replane client as a singleton
var replaneClient = new ReplaneClient(new ReplaneClientOptions
{
Defaults = new Dictionary<string, object?>
{
["api-rate-limit"] = 100,
["premium-feature-enabled"] = false,
["maintenance-mode"] = false,
["welcome-message"] = "Welcome to the API!"
}
});
// Register the client as the interface for easy testing/mocking
builder.Services.AddSingleton<IReplaneClient>(replaneClient);
var app = builder.Build();
// Connect to Replane during startup
try
{
await replaneClient.ConnectAsync(new ConnectOptions
{
BaseUrl = builder.Configuration["Replane:BaseUrl"]
?? Environment.GetEnvironmentVariable("REPLANE_BASE_URL")
?? "https://your-replane-server.com",
SdkKey = builder.Configuration["Replane:SdkKey"]
?? Environment.GetEnvironmentVariable("REPLANE_SDK_KEY")
?? "your-sdk-key"
});
app.Logger.LogInformation("Connected to Replane server");
}
catch (ReplaneException ex)
{
app.Logger.LogWarning("Running with default configs: {Message}", ex.Message);
}
// Middleware: Check maintenance mode
app.Use(async (context, next) =>
{
var client = context.RequestServices.GetRequiredService<IReplaneClient>();
var maintenanceMode = client.Get<bool>("maintenance-mode");
if (maintenanceMode && !context.Request.Path.StartsWithSegments("/health"))
{
context.Response.StatusCode = 503;
await context.Response.WriteAsJsonAsync(new { error = "Service is under maintenance" });
return;
}
await next();
});
// Endpoints
app.MapGet("/", (IReplaneClient client) =>
{
var message = client.Get<string>("welcome-message");
return new { message };
});
app.MapGet("/health", () => new { status = "healthy" });
app.MapGet("/config/{name}", (string name, IReplaneClient client) =>
{
try
{
var value = client.Get<object>(name);
return Results.Ok(new { name, value });
}
catch (ConfigNotFoundException)
{
return Results.NotFound(new { error = $"Config '{name}' not found" });
}
});
app.MapGet("/features", (HttpContext http, IReplaneClient client) =>
{
// Extract user context from request (e.g., from headers or JWT)
var userId = http.Request.Headers["X-User-Id"].FirstOrDefault() ?? "anonymous";
var userPlan = http.Request.Headers["X-User-Plan"].FirstOrDefault() ?? "free";
var context = new ReplaneContext
{
["user_id"] = userId,
["plan"] = userPlan
};
return new
{
userId,
plan = userPlan,
features = new
{
premiumFeatureEnabled = client.Get<bool>("premium-feature-enabled", context),
rateLimit = client.Get<int>("api-rate-limit", context),
}
};
});
// Graceful shutdown
var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
lifetime.ApplicationStopping.Register(() =>
{
app.Logger.LogInformation("Disposing Replane client...");
replaneClient.Dispose();
});
app.Run();