| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- using Astralis;
- using Invercargill;
- using Invercargill.DataStructures;
- using Inversion;
- /**
- * WebConfig Example
- *
- * Demonstrates the WebConfig configuration system:
- * - Accessing configuration values from DI-injected WebConfig
- * - Using different typed getters (string, int, bool, arrays)
- * - Accessing nested sections
- * - Handling missing keys with defaults
- *
- * To run with different environments:
- * ./web-config-example # Uses web-config.json
- * ASTRALIS_ENV=staging ./web-config-example # Uses web-config.json + web-config.staging.json
- */
- // Root endpoint - shows all configuration
- class ConfigRootEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- var json_parts = new Series<string>();
- json_parts.add_start("{\n");
- json_parts.add_start(" \"message\": \"WebConfig Example API\",\n");
- json_parts.add_start(" \"endpoints\": {\n");
- json_parts.add_start(" \"config\": \"/config\",\n");
- json_parts.add_start(" \"database\": \"/config/database\",\n");
- json_parts.add_start(" \"origins\": \"/config/origins\",\n");
- json_parts.add_start(" \"debug\": \"/config/debug\",\n");
- json_parts.add_start(" \"sources\": \"/config/sources\"\n");
- json_parts.add_start(" }\n");
- json_parts.add_start("}");
-
- var json_string = json_parts.to_immutable_buffer()
- .aggregate<string>("", (acc, s) => acc + s);
-
- return new HttpStringResult(json_string)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- // Shows full configuration details
- class ConfigEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- // Get values with defaults for missing keys
- var port = config.get_int("port", 8080);
- var app_name = config.get_string("app_name", "Unknown App");
- var debug = config.get_bool("debug", false);
-
- // Build JSON response
- var json_parts = new Series<string>();
- json_parts.add_start("{\n");
- json_parts.add_start(@" \"port\": $port,\n");
- json_parts.add_start(@" \"app_name\": \"$app_name\",\n");
- json_parts.add_start(@" \"debug\": $debug\n");
- json_parts.add_start("}");
-
- var json_string = json_parts.to_immutable_buffer()
- .aggregate<string>("", (acc, s) => acc + s);
-
- return new HttpStringResult(json_string)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- // Demonstrates accessing nested configuration sections
- class DatabaseConfigEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- // Get the database section
- var db_section = config.get_section("database");
-
- string db_host;
- int db_port;
- string db_name;
-
- if (db_section != null) {
- // Access values from the nested section
- db_host = db_section.get_string("host", "localhost");
- db_port = db_section.get_int("port", 5432);
- db_name = db_section.get_string("name", "app_db");
- } else {
- // Section not configured - use defaults
- db_host = "not configured";
- db_port = 0;
- db_name = "not configured";
- }
-
- // Build JSON response
- var json = @"{
- \"database\": {
- \"host\": \"$db_host\",
- \"port\": $db_port,
- \"name\": \"$db_name\"
- }
- }";
-
- return new HttpStringResult(json)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- // Demonstrates accessing string arrays
- class OriginsConfigEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- // Get string array with default empty array
- var origins = config.get_string_array("allowed_origins", {});
-
- // Build JSON array
- var origins_parts = new Series<string>();
- origins_parts.add_start("[");
-
- bool first = true;
- foreach (var origin in origins) {
- if (!first) origins_parts.add_start(", ");
- origins_parts.add_start(@"\"$origin\"");
- first = false;
- }
-
- origins_parts.add("]");
-
- var origins_json = origins_parts.to_immutable_buffer()
- .aggregate<string>("", (acc, s) => acc + s);
-
- var json = @"{
- \"allowed_origins\": $origins_json,
- \"count\": $(origins.length)
- }";
-
- return new HttpStringResult(json)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- // Demonstrates boolean access and has_key checking
- class DebugConfigEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- // Check if key exists before accessing
- var has_debug = config.has_key("debug");
- var debug = config.get_bool("debug", false);
-
- // Also check for other optional keys
- var has_log_level = config.has_key("log_level");
- var log_level = config.get_string("log_level", "info");
-
- var json = @"{
- \"debug\": {
- \"configured\": $has_debug,
- \"value\": $debug
- },
- \"log_level\": {
- \"configured\": $has_log_level,
- \"value\": \"$log_level\"
- }
- }";
-
- return new HttpStringResult(json)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- // Shows which configuration files were loaded (demonstrates layering)
- class ConfigSourcesEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- // Get list of loaded files
- var loaded_files = config.get_loaded_files();
- var is_loaded = config.is_loaded();
-
- // Build JSON array of sources
- var sources_parts = new Series<string>();
- sources_parts.add_start("[");
-
- bool first = true;
- foreach (var file in loaded_files) {
- if (!first) sources_parts.add_start(", ");
- sources_parts.add_start(@"\"$file\"");
- first = false;
- }
-
- sources_parts.add("]");
-
- var sources_json = sources_parts.to_immutable_buffer()
- .aggregate<string>("", (acc, s) => acc + s);
-
- var json = @"{
- \"loaded\": $is_loaded,
- \"sources\": $sources_json,
- \"to_string\": \"$(config.to_string().replace("\"", "\\\""))\"
- }";
-
- return new HttpStringResult(json)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- // Demonstrates accessing all keys and iterating configuration
- class ConfigKeysEndpoint : Object, Endpoint {
- public async HttpResult handle_request(HttpContext http_context, RouteContext route) throws Error {
- var config = inject<WebConfig>();
-
- // Get all root-level keys
- var keys = config.get_keys();
-
- // Build JSON array of keys
- var keys_parts = new Series<string>();
- keys_parts.add_start("[");
-
- bool first = true;
- foreach (var key in keys) {
- if (!first) keys_parts.add_start(", ");
- keys_parts.add_start(@"\"$key\"");
- first = false;
- }
-
- keys_parts.add("]");
-
- var keys_json = keys_parts.to_immutable_buffer()
- .aggregate<string>("", (acc, s) => acc + s);
-
- var json = @"{
- \"keys\": $keys_json,
- \"count\": $(keys.length())
- }";
-
- return new HttpStringResult(json)
- .set_header("Content-Type", "application/json")
- .set_header("Access-Control-Allow-Origin", "*");
- }
- }
- void main() {
- var application = new WebApplication();
-
- // Register endpoints
- application.container.register_scoped<Endpoint>(() => new ConfigRootEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/"))
- .as<Endpoint>();
-
- application.container.register_scoped<Endpoint>(() => new ConfigEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/config"))
- .as<Endpoint>();
-
- application.container.register_scoped<Endpoint>(() => new DatabaseConfigEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/config/database"))
- .as<Endpoint>();
-
- application.container.register_scoped<Endpoint>(() => new OriginsConfigEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/config/origins"))
- .as<Endpoint>();
-
- application.container.register_scoped<Endpoint>(() => new DebugConfigEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/config/debug"))
- .as<Endpoint>();
-
- application.container.register_scoped<Endpoint>(() => new ConfigSourcesEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/config/sources"))
- .as<Endpoint>();
-
- application.container.register_scoped<Endpoint>(() => new ConfigKeysEndpoint())
- .with_metadata<EndpointRoute>(new EndpointRoute("/config/keys"))
- .as<Endpoint>();
-
- print("WebConfig Example Server starting...\n");
- print("Configuration is loaded from web-config.json (and web-config.{ENV}.json if ASTRALIS_ENV is set)\n");
- print("\nTry these endpoints:\n");
- print(" - http://localhost:3000/\n");
- print(" - http://localhost:3000/config\n");
- print(" - http://localhost:3000/config/database\n");
- print(" - http://localhost:3000/config/origins\n");
- print(" - http://localhost:3000/config/debug\n");
- print(" - http://localhost:3000/config/sources\n");
- print(" - http://localhost:3000/config/keys\n");
- print("\nTo test configuration layering:\n");
- print(" ASTRALIS_ENV=staging ./web-config-example\n");
- print(" Then check /config/sources to see both files loaded\n");
-
- application.run();
- }
|