QueryParameters.vala 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using Astralis;
  2. using Invercargill;
  3. using Invercargill.DataStructures;
  4. /**
  5. * QueryParameters Example
  6. *
  7. * Demonstrates how to handle query parameters in Astralis.
  8. * Uses Invercargill Dictionary for parameter storage and
  9. * Enumerable for processing parameters.
  10. */
  11. // Greet handler - simple query parameter access
  12. class GreetHandler : Object, RouteHandler {
  13. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  14. var name = http_context.request.get_query_or_default("name", "World");
  15. var greeting = http_context.request.get_query_or_default("greeting", "Hello");
  16. return new BufferedHttpResult.from_string(
  17. @"$greeting, $name!"
  18. );
  19. }
  20. }
  21. // Search handler - multiple query parameters with validation
  22. class SearchHandler : Object, RouteHandler {
  23. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  24. var query = http_context.request.get_query("q");
  25. var limit = int.parse(http_context.request.get_query_or_default("limit", "10"));
  26. var offset = int.parse(http_context.request.get_query_or_default("offset", "0"));
  27. if (query == null || query == "") {
  28. var headers = new Catalogue<string, string>();
  29. headers.add("Content-Type", "application/json");
  30. return new BufferedHttpResult.from_string(
  31. @"{ \"error\": \"Query parameter 'q' is required\" }",
  32. StatusCode.BAD_REQUEST,
  33. headers
  34. );
  35. }
  36. // Build response using Enumerable operations
  37. var results = Wrap.array<string>({"Result 1", "Result 2", "Result 3", "Result 4", "Result 5"})
  38. .skip(offset)
  39. .take(limit);
  40. var json_parts = new Series<string>();
  41. json_parts.add(@"{ \"query\": \"$query\", \"results\": [");
  42. bool first = true;
  43. results.iterate((result) => {
  44. if (!first) json_parts.add(", ");
  45. json_parts.add(@"\"$result\"");
  46. first = false;
  47. });
  48. json_parts.add("] }");
  49. var json_string = json_parts.to_immutable_buffer()
  50. .aggregate<string>("", (acc, s) => acc + s);
  51. var headers = new Catalogue<string, string>();
  52. headers.add("Content-Type", "application/json");
  53. return new BufferedHttpResult.from_string(
  54. json_string,
  55. StatusCode.OK,
  56. headers
  57. );
  58. }
  59. }
  60. // Debug handler - boolean flag query parameters
  61. class DebugHandler : Object, RouteHandler {
  62. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  63. var verbose = http_context.request.has_query("verbose");
  64. var level = http_context.request.get_query_or_default("level", "info");
  65. var parts = new Series<string>();
  66. parts.add("Debug Information:\n");
  67. parts.add(@" Verbose mode: $(verbose ? "enabled" : "disabled")\n");
  68. parts.add(@" Log level: $level\n");
  69. // Add query parameters listing using Enumerable
  70. parts.add("\nAll query parameters:\n");
  71. http_context.request.query_params.to_immutable_buffer()
  72. .iterate((grouping) => {
  73. grouping.iterate((value) => {
  74. parts.add(@" - $(grouping.key): $value\n");
  75. });
  76. });
  77. var result = parts.to_immutable_buffer()
  78. .aggregate<string>("", (acc, s) => acc + s);
  79. return new BufferedHttpResult.from_string(result);
  80. }
  81. }
  82. // Filter handler - query parameter with multiple values (comma-separated)
  83. class FilterHandler : Object, RouteHandler {
  84. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  85. var tags_param = http_context.request.get_query("tags");
  86. if (tags_param == null) {
  87. var headers = new Catalogue<string, string>();
  88. headers.add("Content-Type", "application/json");
  89. return new BufferedHttpResult.from_string(
  90. @"{ \"message\": \"No tags provided\" }",
  91. StatusCode.OK,
  92. headers
  93. );
  94. }
  95. // Parse comma-separated tags using Enumerable operations
  96. var tags = Wrap.array<string>(tags_param.split(","))
  97. .select<string>(tag => tag.strip())
  98. .where(tag => tag != "")
  99. .to_vector();
  100. var json_parts = new Series<string>();
  101. json_parts.add(@"{ \"tags\": [");
  102. bool first = true;
  103. tags.to_immutable_buffer().iterate((tag) => {
  104. if (!first) json_parts.add(", ");
  105. json_parts.add(@"\"$tag\"");
  106. first = false;
  107. });
  108. json_parts.add("] }");
  109. var json_string = json_parts.to_immutable_buffer()
  110. .aggregate<string>("", (acc, s) => acc + s);
  111. var headers = new Catalogue<string, string>();
  112. headers.add("Content-Type", "application/json");
  113. return new BufferedHttpResult.from_string(
  114. json_string,
  115. StatusCode.OK,
  116. headers
  117. );
  118. }
  119. }
  120. // Range handler - numeric query parameters with range validation
  121. class RangeHandler : Object, RouteHandler {
  122. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  123. var min = int.parse(http_context.request.get_query_or_default("min", "0"));
  124. var max = int.parse(http_context.request.get_query_or_default("max", "100"));
  125. var step = int.parse(http_context.request.get_query_or_default("step", "1"));
  126. if (min >= max) {
  127. var headers = new Catalogue<string, string>();
  128. headers.add("Content-Type", "application/json");
  129. return new BufferedHttpResult.from_string(
  130. @"{ \"error\": \"min must be less than max\" }",
  131. StatusCode.BAD_REQUEST,
  132. headers
  133. );
  134. }
  135. // Generate range using Iterate.range and Enumerable operations
  136. var numbers = Iterate.range(min, max)
  137. .where(n => (n - min) % step == 0);
  138. var json_parts = new Series<string>();
  139. json_parts.add(@"{ \"min\": $min, \"max\": $max, \"step\": $step, \"numbers\": [");
  140. bool first = true;
  141. numbers.iterate((n) => {
  142. if (!first) json_parts.add(", ");
  143. json_parts.add(n.to_string());
  144. first = false;
  145. });
  146. json_parts.add("] }");
  147. var json_string = json_parts.to_immutable_buffer()
  148. .aggregate<string>("", (acc, s) => acc + s);
  149. var headers = new Catalogue<string, string>();
  150. headers.add("Content-Type", "application/json");
  151. return new BufferedHttpResult.from_string(
  152. json_string,
  153. StatusCode.OK,
  154. headers
  155. );
  156. }
  157. }
  158. void main() {
  159. var router = new Router();
  160. var server = new Server(8081, router);
  161. // Register routes
  162. router.get("/greet", new GreetHandler());
  163. router.get("/search", new SearchHandler());
  164. router.get("/debug", new DebugHandler());
  165. router.get("/filter", new FilterHandler());
  166. router.get("/range", new RangeHandler());
  167. print("Query Parameters Example Server running on port 8081\n");
  168. print("Try these endpoints:\n");
  169. print(" - http://localhost:8081/greet?name=Alice\n");
  170. print(" - http://localhost:8081/search?q=test&limit=3\n");
  171. print(" - http://localhost:8081/debug?verbose&level=debug\n");
  172. print(" - http://localhost:8081/filter?tags=foo,bar,baz\n");
  173. print(" - http://localhost:8081/range?min=1&max=20&step=2\n");
  174. server.run();
  175. }