QueryParameters.vala 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 GreetEndpoint : Object, Endpoint {
  13. public string route { get { return "/greet"; } }
  14. public Method[] methods { owned get { return { Method.GET }; } }
  15. public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
  16. var name = http_context.request.get_query_or_default("name", "World");
  17. var greeting = http_context.request.get_query_or_default("greeting", "Hello");
  18. return new HttpStringResult(@"$greeting, $name!");
  19. }
  20. }
  21. // Search handler - multiple query parameters with validation
  22. class SearchEndpoint : Object, Endpoint {
  23. public string route { get { return "/search"; } }
  24. public Method[] methods { owned get { return { Method.GET }; } }
  25. public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
  26. var query = http_context.request.get_query("q");
  27. var limit = int.parse(http_context.request.get_query_or_default("limit", "10"));
  28. var offset = int.parse(http_context.request.get_query_or_default("offset", "0"));
  29. if (query == null || query == "") {
  30. return new HttpStringResult(@"{ \"error\": \"Query parameter 'q' is required\" }")
  31. .set_header("Content-Type", "application/json");
  32. }
  33. // Build response using Enumerable operations
  34. var results = Wrap.array<string>({"Result 1", "Result 2", "Result 3", "Result 4", "Result 5"})
  35. .skip(offset)
  36. .take(limit);
  37. var json_parts = new Series<string>();
  38. json_parts.add(@"{ \"query\": \"$query\", \"results\": [");
  39. bool first = true;
  40. results.iterate((result) => {
  41. if (!first) json_parts.add(", ");
  42. json_parts.add(@"\"$result\"");
  43. first = false;
  44. });
  45. json_parts.add("] }");
  46. var json_string = json_parts.to_immutable_buffer()
  47. .aggregate<string>("", (acc, s) => acc + s);
  48. return new HttpStringResult(json_string)
  49. .set_header("Content-Type", "application/json");
  50. }
  51. }
  52. // Debug handler - boolean flag query parameters
  53. class DebugEndpoint : Object, Endpoint {
  54. public string route { get { return "/debug"; } }
  55. public Method[] methods { owned get { return { Method.GET }; } }
  56. public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
  57. var verbose = http_context.request.has_query("verbose");
  58. var level = http_context.request.get_query_or_default("level", "info");
  59. var parts = new Series<string>();
  60. parts.add("Debug Information:\n");
  61. parts.add(@" Verbose mode: $(verbose ? "enabled" : "disabled")\n");
  62. parts.add(@" Log level: $level\n");
  63. // Add query parameters listing using Enumerable
  64. parts.add("\nAll query parameters:\n");
  65. http_context.request.query_params.to_immutable_buffer()
  66. .iterate((grouping) => {
  67. grouping.iterate((value) => {
  68. parts.add(@" - $(grouping.key): $value\n");
  69. });
  70. });
  71. var result = parts.to_immutable_buffer()
  72. .aggregate<string>("", (acc, s) => acc + s);
  73. return new HttpStringResult(result);
  74. }
  75. }
  76. // Filter handler - query parameter with multiple values (comma-separated)
  77. class FilterEndpoint : Object, Endpoint {
  78. public string route { get { return "/filter"; } }
  79. public Method[] methods { owned get { return { Method.GET }; } }
  80. public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
  81. var tags_param = http_context.request.get_query("tags");
  82. if (tags_param == null) {
  83. return new HttpStringResult(@"{ \"message\": \"No tags provided\" }")
  84. .set_header("Content-Type", "application/json");
  85. }
  86. // Parse comma-separated tags using Enumerable operations
  87. var tags = Wrap.array<string>(tags_param.split(","))
  88. .select<string>(tag => tag.strip())
  89. .where(tag => tag != "")
  90. .to_vector();
  91. var json_parts = new Series<string>();
  92. json_parts.add(@"{ \"tags\": [");
  93. bool first = true;
  94. tags.to_immutable_buffer().iterate((tag) => {
  95. if (!first) json_parts.add(", ");
  96. json_parts.add(@"\"$tag\"");
  97. first = false;
  98. });
  99. json_parts.add("] }");
  100. var json_string = json_parts.to_immutable_buffer()
  101. .aggregate<string>("", (acc, s) => acc + s);
  102. return new HttpStringResult(json_string)
  103. .set_header("Content-Type", "application/json");
  104. }
  105. }
  106. // Range handler - numeric query parameters with range validation
  107. class RangeEndpoint : Object, Endpoint {
  108. public string route { get { return "/range"; } }
  109. public Method[] methods { owned get { return { Method.GET }; } }
  110. public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
  111. var min = int.parse(http_context.request.get_query_or_default("min", "0"));
  112. var max = int.parse(http_context.request.get_query_or_default("max", "100"));
  113. var step = int.parse(http_context.request.get_query_or_default("step", "1"));
  114. if (min >= max) {
  115. return new HttpStringResult(@"{ \"error\": \"min must be less than max\" }")
  116. .set_header("Content-Type", "application/json");
  117. }
  118. // Generate range using Iterate.range and Enumerable operations
  119. var numbers = Iterate.range(min, max)
  120. .where(n => (n - min) % step == 0);
  121. var json_parts = new Series<string>();
  122. json_parts.add(@"{ \"min\": $min, \"max\": $max, \"step\": $step, \"numbers\": [");
  123. bool first = true;
  124. numbers.iterate((n) => {
  125. if (!first) json_parts.add(", ");
  126. json_parts.add(n.to_string());
  127. first = false;
  128. });
  129. json_parts.add("] }");
  130. var json_string = json_parts.to_immutable_buffer()
  131. .aggregate<string>("", (acc, s) => acc + s);
  132. return new HttpStringResult(json_string)
  133. .set_header("Content-Type", "application/json");
  134. }
  135. }
  136. void main() {
  137. var router = new EndpointRouter()
  138. .add_endpoint(new GreetEndpoint())
  139. .add_endpoint(new SearchEndpoint())
  140. .add_endpoint(new DebugEndpoint())
  141. .add_endpoint(new FilterEndpoint())
  142. .add_endpoint(new RangeEndpoint());
  143. var pipeline = new Pipeline()
  144. .add_component(router);
  145. var server = new Server(8081, pipeline);
  146. print("Query Parameters Example Server running on port 8081\n");
  147. print("Try these endpoints:\n");
  148. print(" - http://localhost:8081/greet?name=Alice\n");
  149. print(" - http://localhost:8081/search?q=test&limit=3\n");
  150. print(" - http://localhost:8081/debug?verbose&level=debug\n");
  151. print(" - http://localhost:8081/filter?tags=foo,bar,baz\n");
  152. print(" - http://localhost:8081/range?min=1&max=20&step=2\n");
  153. server.run();
  154. }