QueryParameters.vala 7.2 KB

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