using Astralis; using Invercargill; using Invercargill.DataStructures; /** * QueryParameters Example * * Demonstrates how to handle query parameters in Astralis. * Uses Invercargill Dictionary for parameter storage and * Enumerable for processing parameters. */ void main() { var router = new Router(); var server = new Server(8081, router); // Simple query parameter access router.map_func("/greet", (context) => { var name = context.request.get_query_or_default("name", "World"); var greeting = context.request.get_query_or_default("greeting", "Hello"); return new BufferedHttpResult.from_string( @"$greeting, $name!" ); }); // Multiple query parameters with validation router.map_func("/search", (context) => { var query = context.request.get_query("q"); var limit = int.parse(context.request.get_query_or_default("limit", "10")); var offset = int.parse(context.request.get_query_or_default("offset", "0")); if (query == null || query == "") { var headers = new Catalogue(); headers.add("Content-Type", "application/json"); return new BufferedHttpResult.from_string( @"{ \"error\": \"Query parameter 'q' is required\" }", StatusCode.BAD_REQUEST, headers ); } // Build response using Enumerable operations var results = Wrap.array({"Result 1", "Result 2", "Result 3", "Result 4", "Result 5"}) .skip(offset) .take(limit); var json_parts = new Series(); json_parts.add(@"{ \"query\": \"$query\", \"results\": ["); bool first = true; results.iterate((result) => { if (!first) json_parts.add(", "); json_parts.add(@"\"$result\""); first = false; }); json_parts.add("] }"); var json_string = json_parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); var headers = new Catalogue(); headers.add("Content-Type", "application/json"); return new BufferedHttpResult.from_string( json_string, StatusCode.OK, headers ); }); // Boolean flag query parameters router.map_func("/debug", (context) => { var verbose = context.request.has_query("verbose"); var level = context.request.get_query_or_default("level", "info"); var parts = new Series(); parts.add("Debug Information:\n"); parts.add(@" Verbose mode: $(verbose ? "enabled" : "disabled")\n"); parts.add(@" Log level: $level\n"); // Add query parameters listing using Enumerable parts.add("\nAll query parameters:\n"); context.request.query_params.to_immutable_buffer() .iterate((grouping) => { grouping.iterate((value) => { parts.add(@" - $(grouping.key): $value\n"); }); }); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new BufferedHttpResult.from_string(result); }); // Query parameter with multiple values (comma-separated) router.map_func("/filter", (context) => { var tags_param = context.request.get_query("tags"); if (tags_param == null) { var headers = new Catalogue(); headers.add("Content-Type", "application/json"); return new BufferedHttpResult.from_string( @"{ \"message\": \"No tags provided\" }", StatusCode.OK, headers ); } // Parse comma-separated tags using Enumerable operations var tags = Wrap.array(tags_param.split(",")) .select(tag => tag.strip()) .where(tag => tag != "") .to_vector(); var json_parts = new Series(); json_parts.add(@"{ \"tags\": ["); bool first = true; tags.to_immutable_buffer().iterate((tag) => { if (!first) json_parts.add(", "); json_parts.add(@"\"$tag\""); first = false; }); json_parts.add("] }"); var json_string = json_parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); var headers = new Catalogue(); headers.add("Content-Type", "application/json"); return new BufferedHttpResult.from_string( json_string, StatusCode.OK, headers ); }); // Numeric query parameters with range validation router.map_func("/range", (context) => { var min = int.parse(context.request.get_query_or_default("min", "0")); var max = int.parse(context.request.get_query_or_default("max", "100")); var step = int.parse(context.request.get_query_or_default("step", "1")); if (min >= max) { var headers = new Catalogue(); headers.add("Content-Type", "application/json"); return new BufferedHttpResult.from_string( @"{ \"error\": \"min must be less than max\" }", StatusCode.BAD_REQUEST, headers ); } // Generate range using Iterate.range and Enumerable operations var numbers = Iterate.range(min, max) .where(n => (n - min) % step == 0); var json_parts = new Series(); json_parts.add(@"{ \"min\": $min, \"max\": $max, \"step\": $step, \"numbers\": ["); bool first = true; numbers.iterate((n) => { if (!first) json_parts.add(", "); json_parts.add(n.to_string()); first = false; }); json_parts.add("] }"); var json_string = json_parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); var headers = new Catalogue(); headers.add("Content-Type", "application/json"); return new BufferedHttpResult.from_string( json_string, StatusCode.OK, headers ); }); print("Query Parameters Example Server running on port 8081\n"); print("Try these endpoints:\n"); print(" - http://localhost:8081/greet?name=Alice\n"); print(" - http://localhost:8081/search?q=test&limit=3\n"); print(" - http://localhost:8081/debug?verbose&level=debug\n"); print(" - http://localhost:8081/filter?tags=foo,bar,baz\n"); print(" - http://localhost:8081/range?min=1&max=20&step=2\n"); server.run(); }