소스 검색

Update examples

Billy Barrow 4 주 전
부모
커밋
d7d272c424

+ 57 - 33
examples/DataStructuresDemo.vala

@@ -9,12 +9,10 @@ using Invercargill.DataStructures;
  * Shows how to use Series, Vector, RingBuffer, and other structures
  * with the Astralis web framework.
  */
-void main() {
-    var router = new Router();
-    var server = new Server(8086, router);
-    
-    // Root endpoint
-    router.map_func("/", (context) => {
+
+// Root handler
+class RootHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             """Data Structures Demo
 
@@ -23,16 +21,18 @@ This example demonstrates various Invercargill data structures:
 Endpoints:
   GET /series                - Series operations
   GET /vector                - Vector operations
-  GET /ring-buffer            - RingBuffer operations
+  GET /ring-buffer           - RingBuffer operations
   GET /immutable-buffer      - ImmutableBuffer operations
   GET /wrap-operations       - Wrap utility functions
-  GET /combined-operations    - Combined operations
+  GET /combined-operations   - Combined operations
 """
         );
-    });
-    
-    // Series operations
-    router.map_func("/series", (context) => {
+    }
+}
+
+// Series operations
+class SeriesHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var series_array = new string[3];
         series_array[0] = "First";
         series_array[1] = "Second";
@@ -52,10 +52,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Vector operations
-    router.map_func("/vector", (context) => {
+    }
+}
+
+// Vector operations
+class VectorHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = new int[5];
         numbers[0] = 1;
         numbers[1] = 2;
@@ -76,10 +78,12 @@ Endpoints:
   Elements: 1, 2, 3, 4, 5";
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // RingBuffer operations
-    router.map_func("/ring-buffer", (context) => {
+    }
+}
+
+// RingBuffer operations
+class RingBufferHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var buffer_array = new string[5];
         buffer_array[0] = "Item 1";
         buffer_array[1] = "Item 2";
@@ -97,10 +101,12 @@ Endpoints:
   Note: RingBuffer automatically overwrites old items when full";
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // ImmutableBuffer operations
-    router.map_func("/immutable-buffer", (context) => {
+    }
+}
+
+// ImmutableBuffer operations
+class ImmutableBufferHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var items_array = new string[4];
         items_array[0] = "Apple";
         items_array[1] = "Banana";
@@ -124,10 +130,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Wrap utility functions
-    router.map_func("/wrap-operations", (context) => {
+    }
+}
+
+// Wrap utility functions
+class WrapOperationsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = new int[5];
         numbers[0] = 1;
         numbers[1] = 2;
@@ -152,10 +160,12 @@ Endpoints:
   Strings: one, two, three, four, five";
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Combined operations
-    router.map_func("/combined-operations", (context) => {
+    }
+}
+
+// Combined operations
+class CombinedOperationsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers1 = new int[3];
         numbers1[0] = 1;
         numbers1[1] = 2;
@@ -193,7 +203,21 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8086, router);
+    
+    // Register routes
+    router.get("/", new RootHandler());
+    router.get("/series", new SeriesHandler());
+    router.get("/vector", new VectorHandler());
+    router.get("/ring-buffer", new RingBufferHandler());
+    router.get("/immutable-buffer", new ImmutableBufferHandler());
+    router.get("/wrap-operations", new WrapOperationsHandler());
+    router.get("/combined-operations", new CombinedOperationsHandler());
     
     print("Data Structures Demo Server running on port 8086\n");
     print("Try these endpoints:\n");

+ 69 - 42
examples/EnumerableOperations.vala

@@ -8,31 +8,31 @@ using Invercargill.DataStructures;
  * Demonstrates various LINQ-like operations available in Invercargill Enumerable.
  * This example shows filtering, mapping, grouping, and aggregation operations.
  */
-void main() {
-    var router = new Router();
-    var server = new Server(8087, router);
-    
-    // Root endpoint
-    router.map_func("/", (context) => {
+
+// Root handler
+class RootHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             """Enumerable Operations Demo
 
 This example demonstrates various LINQ-like operations available in Invercargill Enumerable:
 
 Endpoints:
-  GET /filter                - Filtering examples
-  GET /map                   - Mapping/Projection examples
-  GET /group-by              - Grouping examples
-  GET /aggregate              - Aggregation examples
-  GET /sort                  - Sorting examples
-  GET /set-operations        - Set operations (union, intersection, etc.)
-  GET /advanced               - Advanced operations (zip, partition, etc.)
+  GET /filter              - Filtering examples
+  GET /map                 - Mapping/Projection examples
+  GET /group-by            - Grouping examples
+  GET /aggregate           - Aggregation examples
+  GET /sort                - Sorting examples
+  GET /set-operations      - Set operations (union, intersection, etc.)
+  GET /advanced            - Advanced operations (zip, partition, etc.)
 """
         );
-    });
-    
-    // Filtering examples
-    router.map_func("/filter", (context) => {
+    }
+}
+
+// Filtering examples
+class FilterHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = Wrap.array<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
         
         var parts = new Series<string>();
@@ -72,10 +72,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Mapping/Projection examples
-    router.map_func("/map", (context) => {
+    }
+}
+
+// Mapping/Projection examples
+class MapHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = Wrap.array<int>({1, 2, 3, 4, 5});
         
         var parts = new Series<string>();
@@ -115,10 +117,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Grouping examples
-    router.map_func("/group-by", (context) => {
+    }
+}
+
+// Grouping examples
+class GroupByHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var words = Wrap.array<string>({
             "apple", "banana", "cherry", "apricot", 
             "blueberry", "blackberry", "coconut"
@@ -144,10 +148,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Aggregation examples
-    router.map_func("/aggregate", (context) => {
+    }
+}
+
+// Aggregation examples
+class AggregateHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = Wrap.array<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
         
         var parts = new Series<string>();
@@ -188,10 +194,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Sorting examples
-    router.map_func("/sort", (context) => {
+    }
+}
+
+// Sorting examples
+class SortHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = Wrap.array<int>({5, 2, 8, 1, 9, 3, 7, 4, 6, 10});
         
         var parts = new Series<string>();
@@ -216,10 +224,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Set operations
-    router.map_func("/set-operations", (context) => {
+    }
+}
+
+// Set operations
+class SetOperationsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var set1 = Wrap.array<int>({1, 2, 3, 4, 5});
         var set2 = Wrap.array<int>({4, 5, 6, 7, 8});
         
@@ -252,10 +262,12 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Advanced operations
-    router.map_func("/advanced", (context) => {
+    }
+}
+
+// Advanced operations
+class AdvancedHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var numbers = Wrap.array<int>({1, 2, 3, 4, 5});
         
         var parts = new Series<string>();
@@ -288,7 +300,22 @@ Endpoints:
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8087, router);
+    
+    // Register routes
+    router.get("/", new RootHandler());
+    router.get("/filter", new FilterHandler());
+    router.get("/map", new MapHandler());
+    router.get("/group-by", new GroupByHandler());
+    router.get("/aggregate", new AggregateHandler());
+    router.get("/sort", new SortHandler());
+    router.get("/set-operations", new SetOperationsHandler());
+    router.get("/advanced", new AdvancedHandler());
     
     print("Enumerable Operations Demo Server running on port 8087\n");
     print("Try these endpoints:\n");

+ 107 - 77
examples/ErrorHandling.vala

@@ -8,12 +8,10 @@ using Invercargill.DataStructures;
  * Demonstrates error handling and status codes in Astralis.
  * Uses Invercargill data structures for error logging and management.
  */
-void main() {
-    var router = new Router();
-    var server = new Server(8088, router);
-    
-    // Root endpoint
-    router.map_func("/", (context) => {
+
+// Root handler
+class RootHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             """Error Handling Demo
 
@@ -23,7 +21,7 @@ Endpoints:
   GET /ok                    - 200 OK response
   GET /not-found             - 404 Not Found
   GET /bad-request           - 400 Bad Request
-  GET /internal-error         - 500 Internal Server Error
+  GET /internal-error        - 500 Internal Server Error
   GET /validation            - Input validation example
   GET /resource/{id}         - Resource lookup with error handling
   GET /api/{endpoint}        - API endpoint simulation
@@ -34,48 +32,58 @@ Endpoints:
   GET /method-not-allowed    - 405 Method Not Allowed
 """
         );
-    });
-    
-    // 200 OK response
-    router.map_func("/ok", (context) => {
+    }
+}
+
+// 200 OK response
+class OkHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             @"{ \"status\": \"success\", \"message\": \"Request completed successfully\" }",
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // 404 Not Found
-    router.map_func("/not-found", (context) => {
+    }
+}
+
+// 404 Not Found
+class NotFoundHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             @"{ \"error\": \"Not Found\", \"message\": \"The requested resource was not found\" }",
             StatusCode.NOT_FOUND,
             get_json_headers()
         );
-    });
-    
-    // 400 Bad Request
-    router.map_func("/bad-request", (context) => {
+    }
+}
+
+// 400 Bad Request
+class BadRequestHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             @"{ \"error\": \"Bad Request\", \"message\": \"The request could not be understood\" }",
             StatusCode.BAD_REQUEST,
             get_json_headers()
         );
-    });
-    
-    // 500 Internal Server Error
-    router.map_func("/internal-error", (context) => {
+    }
+}
+
+// 500 Internal Server Error
+class InternalErrorHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             @"{ \"error\": \"Internal Server Error\", \"message\": \"An unexpected error occurred\" }",
             StatusCode.INTERNAL_SERVER_ERROR,
             get_json_headers()
         );
-    });
-    
-    // Input validation example
-    router.map_func("/validation", (context) => {
-        var email = context.request.get_query("email");
-        var age_str = context.request.get_query("age");
+    }
+}
+
+// Input validation example
+class ValidationHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var email = http_context.request.get_query("email");
+        var age_str = http_context.request.get_query("age");
         
         var error_list = new List<string>();
         
@@ -123,17 +131,13 @@ Endpoints:
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Resource lookup with error handling
-    router.map_func("/resource/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 2) {
-            return error_response("Resource ID is required", StatusCode.BAD_REQUEST);
-        }
-        
-        var id_str = components[1];
+    }
+}
+
+// Resource lookup with error handling
+class ResourceHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
         int id;
         
         if (!int.try_parse(id_str, out id)) {
@@ -163,17 +167,13 @@ Endpoints:
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // API endpoint simulation
-    router.map_func("/api/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 2) {
-            return error_response("API endpoint required", StatusCode.BAD_REQUEST);
-        }
-        
-        var endpoint = components[1];
+    }
+}
+
+// API endpoint simulation
+class ApiEndpointHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var endpoint = route_context.get_segment("endpoint");
         
         // Simulate different API responses
         switch (endpoint) {
@@ -197,12 +197,14 @@ Endpoints:
             default:
                 return error_response(@"Unknown endpoint: $endpoint", StatusCode.NOT_FOUND);
         }
-    });
-    
-    // Custom error response
-    router.map_func("/custom-error", (context) => {
-        var error_code = context.request.get_query_or_default("code", "CUSTOM_ERROR");
-        var message = context.request.get_query_or_default("message", "A custom error occurred");
+    }
+}
+
+// Custom error response
+class CustomErrorHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var error_code = http_context.request.get_query_or_default("code", "CUSTOM_ERROR");
+        var message = http_context.request.get_query_or_default("message", "A custom error occurred");
         
         var timestamp = new DateTime.now_local().format_iso8601();
         var request_id = generate_request_id();
@@ -218,20 +220,24 @@ Endpoints:
             StatusCode.BAD_REQUEST,
             get_json_headers()
         );
-    });
-    
-    // Simulated timeout (actually returns 408)
-    router.map_func("/timeout", (context) => {
+    }
+}
+
+// Simulated timeout (actually returns 408)
+class TimeoutHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             @"{ \"error\": \"Request Timeout\", \"message\": \"The request took too long to complete\" }",
             StatusCode.INTERNAL_SERVER_ERROR,
             get_json_headers()
         );
-    });
-    
-    // 401 Unauthorized
-    router.map_func("/unauthorized", (context) => {
-        var auth_header = context.request.get_header("Authorization");
+    }
+}
+
+// 401 Unauthorized
+class UnauthorizedHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var auth_header = http_context.request.get_header("Authorization");
         
         if (auth_header == null) {
             var headers = new Catalogue<string, string>();
@@ -261,11 +267,13 @@ Endpoints:
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // 403 Forbidden
-    router.map_func("/forbidden", (context) => {
-        var user_role = context.request.get_cookie("role") ?? "guest";
+    }
+}
+
+// 403 Forbidden
+class ForbiddenHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var user_role = http_context.request.get_cookie("role") ?? "guest";
         
         if (user_role != "admin") {
             return new BufferedHttpResult.from_string(
@@ -280,10 +288,12 @@ Endpoints:
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // 405 Method Not Allowed
-    router.map_func("/method-not-allowed", (context) => {
+    }
+}
+
+// 405 Method Not Allowed
+class MethodNotAllowedHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var headers = new Catalogue<string, string>();
         headers.add("Allow", "POST, PUT, DELETE");
         
@@ -292,7 +302,27 @@ Endpoints:
             StatusCode.METHOD_NOT_ALLOWED,
             headers
         );
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8088, router);
+    
+    // Register routes
+    router.get("/", new RootHandler());
+    router.get("/ok", new OkHandler());
+    router.get("/not-found", new NotFoundHandler());
+    router.get("/bad-request", new BadRequestHandler());
+    router.get("/internal-error", new InternalErrorHandler());
+    router.get("/validation", new ValidationHandler());
+    router.get("/resource/{id}", new ResourceHandler());
+    router.get("/api/{endpoint}", new ApiEndpointHandler());
+    router.get("/custom-error", new CustomErrorHandler());
+    router.get("/timeout", new TimeoutHandler());
+    router.get("/unauthorized", new UnauthorizedHandler());
+    router.get("/forbidden", new ForbiddenHandler());
+    router.get("/method-not-allowed", new MethodNotAllowedHandler());
     
     print("Error Handling Demo Server running on port 8088\n");
     print("Try these endpoints:\n");
@@ -316,7 +346,7 @@ Endpoints:
 
 // Helper functions
 
-BufferedHttpResult error_response(string message, int status) {
+BufferedHttpResult error_response(string message, StatusCode status) {
     var json = @"{ \"error\": \"Error\", \"message\": \"$message\" }";
     return new BufferedHttpResult.from_string(
         json,

+ 19 - 19
examples/FormData.vala

@@ -5,13 +5,13 @@ using Invercargill.DataStructures;
 /**
  * FormData Example
  * 
- * Demonstrates handling POST form data in Astralis using async HttpHandler.
+ * Demonstrates handling POST form data in Astralis using async RouteHandler.
  * Shows both application/x-www-form-urlencoded and multipart/form-data handling.
  */
 
 // HTML form page handler
-class FormPageHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) throws Error {
+class FormPageHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext context, RouteContext route_context) throws Error {
         var headers = new Catalogue<string, string>();
         headers.add("Content-Type", "text/html");
         return new BufferedHttpResult.from_string(
@@ -128,8 +128,8 @@ class FormPageHandler : Object, RequestHandler {
 }
 
 // Simple form submission handler
-class SimpleFormHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) throws Error {
+class SimpleFormHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext context, RouteContext route_context) throws Error {
         if (!context.request.is_post()) {
             return new BufferedHttpResult.from_string(
                 "Please use POST method",
@@ -168,8 +168,8 @@ class SimpleFormHandler : Object, RequestHandler {
 }
 
 // Registration form submission handler
-class RegisterFormHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) throws Error {
+class RegisterFormHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext context, RouteContext route_context) throws Error {
         if (!context.request.is_post()) {
             return new BufferedHttpResult.from_string(
                 "Please use POST method",
@@ -245,8 +245,8 @@ class RegisterFormHandler : Object, RequestHandler {
 }
 
 // Search form submission handler
-class SearchFormHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) throws Error {
+class SearchFormHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext context, RouteContext route_context) throws Error {
         if (!context.request.is_post()) {
             return new BufferedHttpResult.from_string(
                 "Please use POST method",
@@ -318,8 +318,8 @@ class SearchFormHandler : Object, RequestHandler {
 }
 
 // File upload handler (multipart/form-data)
-class FileUploadHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) throws Error {
+class FileUploadHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext context, RouteContext route_context) throws Error {
         if (!context.request.is_post()) {
             return new BufferedHttpResult.from_string(
                 "Please use POST method",
@@ -358,8 +358,8 @@ class FileUploadHandler : Object, RequestHandler {
 }
 
 // Form debug tool handler
-class FormDebugHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) throws Error {
+class FormDebugHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext context, RouteContext route_context) throws Error {
         FormData? form_data = null;
         string? body_text = null;
         
@@ -540,12 +540,12 @@ void main() {
     var server = new Server(8084, router);
     
     // Register handlers
-    router.map("/", new FormPageHandler());
-    router.map("/submit-simple", new SimpleFormHandler());
-    router.map("/submit-register", new RegisterFormHandler());
-    router.map("/submit-search", new SearchFormHandler());
-    router.map("/submit-file", new FileUploadHandler());
-    router.map("/form-debug", new FormDebugHandler());
+    router.get("/", new FormPageHandler());
+    router.post("/submit-simple", new SimpleFormHandler());
+    router.post("/submit-register", new RegisterFormHandler());
+    router.post("/submit-search", new SearchFormHandler());
+    router.post("/submit-file", new FileUploadHandler());
+    router.map("/form-debug", new FormDebugHandler());  // Handles both GET and POST
     
     print("Form Data Example Server running on port 8084\n");
     print("Open http://localhost:8084/ in your browser to try the forms\n");

+ 140 - 108
examples/HeadersAndCookies.vala

@@ -8,17 +8,15 @@ using Invercargill.DataStructures;
  * Demonstrates how to access and manipulate HTTP headers and cookies.
  * Uses Invercargill Dictionary and Enumerable for header/cookie processing.
  */
-void main() {
-    var router = new Router();
-    var server = new Server(8083, router);
-    
-    // Display all request headers
-    router.map_func("/headers", (context) => {
+
+// Display all request headers
+class HeadersHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var parts = new Series<string>();
         parts.add("Request Headers:\n");
         parts.add("================\n\n");
         
-        context.request.headers.to_immutable_buffer()
+        http_context.request.headers.to_immutable_buffer()
             .iterate((grouping) => {
                 grouping.iterate((value) => {
                     parts.add(@"$(grouping.key): $value\n");
@@ -29,46 +27,53 @@ void main() {
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Check for specific header
-    router.map_func("/user-agent", (context) => {
-        var user_agent = context.request.user_agent ?? "Unknown";
+    }
+}
+
+// Check for user-agent header
+class UserAgentHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var user_agent = http_context.request.user_agent ?? "Unknown";
         
         return new BufferedHttpResult.from_string(
             @"Your User-Agent is: $user_agent"
         );
-    });
-    
-    // Check content type and content length
-    router.map_func("/content-info", (context) => {
+    }
+}
+
+// Check content type and content length
+class ContentInfoHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var parts = new Series<string>();
         parts.add("Content Information:\n");
         parts.add("===================\n\n");
-        parts.add(@"Content-Type: $(context.request.content_type)\n");
-        parts.add(@"Content-Length: $(context.request.content_length)\n");
-        parts.add(@"Content-Encoding: $(context.request.content_encoding ?? "none")\n");
-        //  parts.add(@"Has Body: $(context.request.has_body())\n");
+        parts.add(@"Content-Type: $(http_context.request.content_type)\n");
+        parts.add(@"Content-Length: $(http_context.request.content_length)\n");
+        parts.add(@"Content-Encoding: $(http_context.request.content_encoding ?? "none")\n");
         
         var result = parts.to_immutable_buffer()
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Check if header exists
-    router.map_func("/check-header", (context) => {
-        var header_name = context.request.get_query_or_default("name", "Accept");
-        var exists = context.request.has_header(header_name);
-        var value = context.request.get_header(header_name);
+    }
+}
+
+// Check if header exists
+class CheckHeaderHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var header_name = http_context.request.get_query_or_default("name", "Accept");
+        var exists = http_context.request.has_header(header_name);
+        var value = http_context.request.get_header(header_name);
         
         return new BufferedHttpResult.from_string(
             @"Header '$header_name': $(exists ? "EXISTS" : "NOT FOUND")\nValue: $(value ?? "N/A")"
         );
-    });
-    
-    // Set custom response headers
-    router.map_func("/custom-headers", (context) => {
+    }
+}
+
+// Set custom response headers
+class CustomHeadersHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var headers = new Catalogue<string, string>();
         headers.add("X-Custom-Header", "Custom-Value");
         headers.add("X-Request-Id", generate_request_id());
@@ -80,19 +85,21 @@ void main() {
             StatusCode.OK,
             headers
         );
-    });
-    
-    // Display all cookies
-    router.map_func("/cookies", (context) => {
+    }
+}
+
+// Display all cookies
+class CookiesHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var parts = new Series<string>();
         parts.add("Request Cookies:\n");
         parts.add("================\n\n");
         
-        if (context.request.cookies.to_immutable_buffer().count() == 0) {
+        if (http_context.request.cookies.to_immutable_buffer().count() == 0) {
             parts.add("(No cookies sent)\n");
             parts.add("\nTry setting a cookie first: /set-cookie?name=test&value=123\n");
         } else {
-            context.request.cookies.to_immutable_buffer()
+            http_context.request.cookies.to_immutable_buffer()
                 .iterate((grouping) => {
                     grouping.iterate((value) => {
                         parts.add(@"$(grouping.key): $value\n");
@@ -104,12 +111,14 @@ void main() {
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
-    
-    // Get specific cookie
-    router.map_func("/get-cookie", (context) => {
-        var name = context.request.get_query_or_default("name", "session");
-        var value = context.request.get_cookie(name);
+    }
+}
+
+// Get specific cookie
+class GetCookieHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var name = http_context.request.get_query_or_default("name", "session");
+        var value = http_context.request.get_cookie(name);
         
         if (value == null) {
             return new BufferedHttpResult.from_string(
@@ -121,13 +130,15 @@ void main() {
         return new BufferedHttpResult.from_string(
             @"Cookie '$name' = '$value'"
         );
-    });
-    
-    // Set a cookie (via Set-Cookie header)
-    router.map_func("/set-cookie", (context) => {
-        var name = context.request.get_query_or_default("name", "test");
-        var value = context.request.get_query_or_default("value", "123");
-        var max_age = context.request.get_query_or_default("max_age", "3600");
+    }
+}
+
+// Set a cookie (via Set-Cookie header)
+class SetCookieHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var name = http_context.request.get_query_or_default("name", "test");
+        var value = http_context.request.get_query_or_default("value", "123");
+        var max_age = http_context.request.get_query_or_default("max_age", "3600");
         
         var headers = new Catalogue<string, string>();
         headers.add("Set-Cookie", @"$name=$value; Max-Age=$max_age; Path=/");
@@ -137,10 +148,12 @@ void main() {
             StatusCode.OK,
             headers
         );
-    });
-    
-    // Set multiple cookies
-    router.map_func("/set-cookies", (context) => {
+    }
+}
+
+// Set multiple cookies
+class SetCookiesHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var headers = new Catalogue<string, string>();
         headers.add("Set-Cookie", "user=john; Max-Age=3600; Path=/");
         headers.add("Set-Cookie", "theme=dark; Max-Age=86400; Path=/");
@@ -151,11 +164,13 @@ void main() {
             StatusCode.OK,
             headers
         );
-    });
-    
-    // Delete a cookie
-    router.map_func("/delete-cookie", (context) => {
-        var name = context.request.get_query_or_default("name", "test");
+    }
+}
+
+// Delete a cookie
+class DeleteCookieHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var name = http_context.request.get_query_or_default("name", "test");
         
         var headers = new Catalogue<string, string>();
         headers.add("Set-Cookie", @"$name=; Max-Age=0; Path=/");
@@ -165,21 +180,25 @@ void main() {
             StatusCode.OK,
             headers
         );
-    });
-    
-    // Check if cookie exists
-    router.map_func("/has-cookie", (context) => {
-        var name = context.request.get_query_or_default("name", "session");
-        var exists = context.request.has_cookie(name);
+    }
+}
+
+// Check if cookie exists
+class HasCookieHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var name = http_context.request.get_query_or_default("name", "session");
+        var exists = http_context.request.has_cookie(name);
         
         return new BufferedHttpResult.from_string(
             @"Cookie '$name': $(exists ? "EXISTS" : "NOT FOUND")"
         );
-    });
-    
-    // Cookie-based session simulation
-    router.map_func("/session", (context) => {
-        var session_id = context.request.get_cookie("session_id");
+    }
+}
+
+// Cookie-based session simulation
+class SessionHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var session_id = http_context.request.get_cookie("session_id");
         
         if (session_id == null) {
             // Create new session
@@ -205,11 +224,13 @@ Session ID: $session_id
 
 Your session is active."
         );
-    });
-    
-    // CORS headers example
-    router.map_func("/cors", (context) => {
-        var origin = context.request.get_header("Origin") ?? "*";
+    }
+}
+
+// CORS headers example
+class CorsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var origin = http_context.request.get_header("Origin") ?? "*";
         
         var headers = new Catalogue<string, string>();
         headers.add("Access-Control-Allow-Origin", origin);
@@ -222,29 +243,13 @@ Your session is active."
             StatusCode.OK,
             headers
         );
-    });
-    
-    // OPTIONS method for CORS preflight
-    router.map_func("/cors", (context) => {
-        var origin = context.request.get_header("Origin") ?? "*";
-        
-        var headers = new Catalogue<string, string>();
-        headers.add("Access-Control-Allow-Origin", origin);
-        headers.add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-        headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
-        headers.add("Access-Control-Max-Age", "86400");
-        headers.add("Content-Length", "0");
-        
-        return new BufferedHttpResult.from_string(
-            "",
-            StatusCode.NO_CONTENT,
-            headers
-        );
-    });
-    
-    // Cache control headers
-    router.map_func("/cache", (context) => {
-        var cache_type = context.request.get_query_or_default("type", "public");
+    }
+}
+
+// Cache control headers
+class CacheHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var cache_type = http_context.request.get_query_or_default("type", "public");
         
         var headers = new Catalogue<string, string>();
         headers.add("Cache-Control", @"$cache_type, max-age=3600");
@@ -256,11 +261,13 @@ Your session is active."
             StatusCode.OK,
             headers
         );
-    });
-    
-    // Content negotiation
-    router.map_func("/negotiate", (context) => {
-        var accept = context.request.get_header("Accept") ?? "*/*";
+    }
+}
+
+// Content negotiation
+class NegotiateHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var accept = http_context.request.get_header("Accept") ?? "*/*";
         
         var headers = new Catalogue<string, string>();
         
@@ -286,10 +293,12 @@ Your session is active."
                 headers
             );
         }
-    });
-    
-    // Security headers
-    router.map_func("/secure", (context) => {
+    }
+}
+
+// Security headers
+class SecureHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var headers = new Catalogue<string, string>();
         headers.add("X-Content-Type-Options", "nosniff");
         headers.add("X-Frame-Options", "DENY");
@@ -303,7 +312,30 @@ Your session is active."
             StatusCode.OK,
             headers
         );
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8083, router);
+    
+    // Register routes
+    router.get("/headers", new HeadersHandler());
+    router.get("/user-agent", new UserAgentHandler());
+    router.get("/content-info", new ContentInfoHandler());
+    router.get("/check-header", new CheckHeaderHandler());
+    router.get("/custom-headers", new CustomHeadersHandler());
+    router.get("/cookies", new CookiesHandler());
+    router.get("/get-cookie", new GetCookieHandler());
+    router.get("/set-cookie", new SetCookieHandler());
+    router.get("/set-cookies", new SetCookiesHandler());
+    router.get("/delete-cookie", new DeleteCookieHandler());
+    router.get("/has-cookie", new HasCookieHandler());
+    router.get("/session", new SessionHandler());
+    router.get("/cors", new CorsHandler());
+    router.get("/cache", new CacheHandler());
+    router.get("/negotiate", new NegotiateHandler());
+    router.get("/secure", new SecureHandler());
     
     print("Headers and Cookies Example Server running on port 8083\n");
     print("Try these endpoints:\n");

+ 95 - 74
examples/JsonApi.vala

@@ -9,12 +9,10 @@ using Invercargill.DataStructures;
  * Uses Invercargill data structures for data management and
  * Enumerable for JSON serialization.
  */
-void main() {
-    var router = new Router();
-    var server = new Server(8085, router);
-    
-    // API root
-    router.map_func("/api", (context) => {
+
+// API root handler
+class ApiRootHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var json = @"{
   \"name\": \"Astralis JSON API\",
   \"version\": \"1.0.0\",
@@ -31,10 +29,12 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // List all users
-    router.map_func("/api/users", (context) => {
+    }
+}
+
+// List all users
+class UsersListHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var users = get_users();
         
         var json_parts = new Series<string>();
@@ -59,17 +59,14 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Get user by ID
-    router.map_func("/api/users/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 3) {
-            return error_response("User ID required");
-        }
-        
-        var id = int.parse(components[2]);
+    }
+}
+
+// Get user by ID
+class UserByIdHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
+        var id = int.parse(id_str);
         var user = find_user(id);
         
         if (user == null) {
@@ -81,14 +78,16 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // List all posts
-    router.map_func("/api/posts", (context) => {
+    }
+}
+
+// List all posts
+class PostsListHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var posts = get_posts();
         
         // Filter by user_id if provided
-        var user_id_param = context.request.get_query("user_id");
+        var user_id_param = http_context.request.get_query("user_id");
         if (user_id_param != null) {
             var user_id = int.parse(user_id_param);
             posts = posts.to_immutable_buffer()
@@ -118,17 +117,14 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Get post by ID
-    router.map_func("/api/posts/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 3) {
-            return error_response("Post ID required");
-        }
-        
-        var id = int.parse(components[2]);
+    }
+}
+
+// Get post by ID
+class PostByIdHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
+        var id = int.parse(id_str);
         var post = find_post(id);
         
         if (post == null) {
@@ -167,14 +163,16 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // List all comments
-    router.map_func("/api/comments", (context) => {
+    }
+}
+
+// List all comments
+class CommentsListHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var comments = get_comments();
         
         // Filter by post_id if provided
-        var post_id_param = context.request.get_query("post_id");
+        var post_id_param = http_context.request.get_query("post_id");
         if (post_id_param != null) {
             var post_id = int.parse(post_id_param);
             comments = comments.to_immutable_buffer()
@@ -204,17 +202,14 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Get comment by ID
-    router.map_func("/api/comments/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 3) {
-            return error_response("Comment ID required");
-        }
-        
-        var id = int.parse(components[2]);
+    }
+}
+
+// Get comment by ID
+class CommentByIdHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
+        var id = int.parse(id_str);
         var comment = find_comment(id);
         
         if (comment == null) {
@@ -226,10 +221,12 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // API statistics
-    router.map_func("/api/stats", (context) => {
+    }
+}
+
+// API statistics
+class StatsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var users = get_users();
         var posts = get_posts();
         var comments = get_comments();
@@ -253,11 +250,13 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Search endpoint
-    router.map_func("/api/search", (context) => {
-        var query = context.request.get_query("q");
+    }
+}
+
+// Search endpoint
+class SearchHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var query = http_context.request.get_query("q");
         
         if (query == null || query == "") {
             return error_response("Query parameter 'q' is required");
@@ -301,12 +300,14 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Pagination example
-    router.map_func("/api/posts/paginated", (context) => {
-        var page = int.parse(context.request.get_query_or_default("page", "1"));
-        var per_page = int.parse(context.request.get_query_or_default("per_page", "10"));
+    }
+}
+
+// Pagination example
+class PaginatedPostsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var page = int.parse(http_context.request.get_query_or_default("page", "1"));
+        var per_page = int.parse(http_context.request.get_query_or_default("per_page", "10"));
         
         var posts = get_posts();
         var total = posts.to_immutable_buffer().count();
@@ -338,11 +339,13 @@ void main() {
             StatusCode.OK,
             get_json_headers()
         );
-    });
-    
-    // Error handling endpoint
-    router.map_func("/api/error", (context) => {
-        var error_type = context.request.get_query_or_default("type", "generic");
+    }
+}
+
+// Error handling endpoint
+class ApiErrorHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var error_type = http_context.request.get_query_or_default("type", "generic");
         
         switch (error_type) {
             case "not_found":
@@ -354,7 +357,25 @@ void main() {
             default:
                 return error_response("An error occurred");
         }
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8085, router);
+    
+    // Register routes
+    router.get("/api", new ApiRootHandler());
+    router.get("/api/users", new UsersListHandler());
+    router.get("/api/users/{id}", new UserByIdHandler());
+    router.get("/api/posts", new PostsListHandler());
+    router.get("/api/posts/{id}", new PostByIdHandler());
+    router.get("/api/comments", new CommentsListHandler());
+    router.get("/api/comments/{id}", new CommentByIdHandler());
+    router.get("/api/stats", new StatsHandler());
+    router.get("/api/search", new SearchHandler());
+    router.get("/api/posts/paginated", new PaginatedPostsHandler());
+    router.get("/api/error", new ApiErrorHandler());
     
     print("JSON API Example Server running on port 8085\n");
     print("Try these endpoints:\n");

+ 125 - 175
examples/PathRouting.vala

@@ -6,17 +6,15 @@ using Invercargill.DataStructures;
  * PathRouting Example
  * 
  * Demonstrates path component parsing and routing in Astralis.
- * Uses Invercargill Enumerable for path processing.
+ * Uses the Router's named segment feature for dynamic routing.
  */
-void main() {
-    var router = new Router();
-    var server = new Server(8082, router);
-    
-    // Root path
-    router.map_func("/", (context) => {
+
+// Root handler - shows available endpoints
+class RootHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string(
             """Welcome to the Path Routing Example!
-            
+
 Available endpoints:
   GET /                           - This message
   GET /hello                      - Simple greeting
@@ -25,35 +23,32 @@ Available endpoints:
   GET /users/{id}                 - Get user by ID
   GET /users/{id}/posts           - Get posts for a user
   GET /api/v1/status              - API status
-  GET /api/v1/items/{id}         - Get item by ID
+  GET /api/v1/items/{id}          - Get item by ID
   GET /files/{category}/{name}    - Get file by category and name
+  GET /pathinfo                   - Path information demo
 """
         );
-    });
-    
-    // Simple path
-    router.map_func("/hello", (context) => {
+    }
+}
+
+// Simple hello handler
+class HelloHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         return new BufferedHttpResult.from_string("Hello, World!");
-    });
-    
-    // Path with one component (simulated dynamic routing)
-    router.map_func("/hello/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 2) {
-            return new BufferedHttpResult.from_string(
-                "Please provide a name: /hello/{name}",
-                StatusCode.BAD_REQUEST
-            );
-        }
-        
-        var name = components[1];
+    }
+}
+
+// Hello with name handler - uses named segment
+class HelloNameHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var name = route_context.get_segment("name");
         return new BufferedHttpResult.from_string(@"Hello, $name!");
-    });
-    
-    // Users list endpoint
-    router.map_func("/users", (context) => {
-        // Simulated user data using Invercargill data structures
+    }
+}
+
+// Users list handler
+class UsersHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var users = new Series<User>();
         users.add(new User(1, "Alice", "alice@example.com"));
         users.add(new User(2, "Bob", "bob@example.com"));
@@ -81,23 +76,13 @@ Available endpoints:
             StatusCode.OK,
             headers
         );
-    });
-    
-    // User by ID endpoint (simulated)
-    router.map_func("/users/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 2) {
-            var headers = new Catalogue<string, string>();
-            headers.add("Content-Type", "application/json");
-            return new BufferedHttpResult.from_string(
-                @"{ \"error\": \"User ID required\" }",
-                StatusCode.BAD_REQUEST,
-                headers
-            );
-        }
-        
-        var id_str = components[1];
+    }
+}
+
+// User by ID handler - uses named segment
+class UserByIdHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
         var id = int.parse(id_str);
         
         // Simulated user lookup
@@ -126,89 +111,48 @@ Available endpoints:
             StatusCode.OK,
             headers
         );
-    });
-    
-    // User posts endpoint (nested path)
-    router.map_func("/users/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        // Check for /users/{id}/posts pattern
-        if (components.count() >= 3 && components[2] == "posts") {
-            var id_str = components[1];
-            var id = int.parse(id_str);
-            
-            // Simulated posts for user
-            var posts = new Series<Post>();
-            posts.add(new Post(101, id, "First Post", "This is my first post"));
-            posts.add(new Post(102, id, "Second Post", "This is my second post"));
-            
-            var json_parts = new Series<string>();
-            json_parts.add(@"{ \"user_id\": $id, \"posts\": [");
-            
-            bool first = true;
-            posts.to_immutable_buffer().iterate((post) => {
-                if (!first) json_parts.add(", ");
-                json_parts.add(post.to_json());
-                first = false;
-            });
-            
-            json_parts.add("] }");
-            
-            var json_string = json_parts.to_immutable_buffer()
-                .aggregate<string>("", (acc, s) => acc + s);
-            
-            var headers = new Catalogue<string, string>();
-            headers.add("Content-Type", "application/json");
-            return new BufferedHttpResult.from_string(
-                json_string,
-                StatusCode.OK,
-                headers
-            );
-        }
+    }
+}
+
+// User posts handler - uses named segment
+class UserPostsHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
+        var id = int.parse(id_str);
         
-        // Fall back to user detail
-        if (components.count() < 2) {
-            var headers = new Catalogue<string, string>();
-            headers.add("Content-Type", "application/json");
-            return new BufferedHttpResult.from_string(
-                @"{ \"error\": \"User ID required\" }",
-                StatusCode.BAD_REQUEST,
-                headers
-            );
-        }
+        // Simulated posts for user
+        var posts = new Series<Post>();
+        posts.add(new Post(101, id, "First Post", "This is my first post"));
+        posts.add(new Post(102, id, "Second Post", "This is my second post"));
         
-        var id_str = components[1];
-        var id = int.parse(id_str);
+        var json_parts = new Series<string>();
+        json_parts.add(@"{ \"user_id\": $id, \"posts\": [");
         
-        var users = new Series<User>();
-        users.add(new User(1, "Alice", "alice@example.com"));
-        users.add(new User(2, "Bob", "bob@example.com"));
-        users.add(new User(3, "Charlie", "charlie@example.com"));
+        bool first = true;
+        posts.to_immutable_buffer().iterate((post) => {
+            if (!first) json_parts.add(", ");
+            json_parts.add(post.to_json());
+            first = false;
+        });
         
-        var user = users.to_immutable_buffer()
-            .first_or_default(u => u.id == id);
+        json_parts.add("] }");
         
-        if (user == null) {
-            var headers = new Catalogue<string, string>();
-            headers.add("Content-Type", "application/json");
-            return new BufferedHttpResult.from_string(
-                @"{ \"error\": \"User not found\" }",
-                StatusCode.NOT_FOUND,
-                headers
-            );
-        }
+        var json_string = json_parts.to_immutable_buffer()
+            .aggregate<string>("", (acc, s) => acc + s);
         
         var headers = new Catalogue<string, string>();
         headers.add("Content-Type", "application/json");
         return new BufferedHttpResult.from_string(
-            user.to_json(),
+            json_string,
             StatusCode.OK,
             headers
         );
-    });
-    
-    // API versioned endpoint
-    router.map_func("/api/v1/status", (context) => {
+    }
+}
+
+// API status handler
+class ApiStatusHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var status = new Dictionary<string, string>();
         status.set("status", "operational");
         status.set("version", "1.0.0");
@@ -236,23 +180,13 @@ Available endpoints:
             StatusCode.OK,
             headers
         );
-    });
-    
-    // API items endpoint
-    router.map_func("/api/v1/items/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 4) {
-            var headers = new Catalogue<string, string>();
-            headers.add("Content-Type", "application/json");
-            return new BufferedHttpResult.from_string(
-                @"{ \"error\": \"Item ID required\" }",
-                StatusCode.BAD_REQUEST,
-                headers
-            );
-        }
-        
-        var id_str = components[3];
+    }
+}
+
+// API item handler - uses named segment
+class ApiItemHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var id_str = route_context.get_segment("id");
         var id = int.parse(id_str);
         
         var items = new Dictionary<int, Item>();
@@ -278,41 +212,31 @@ Available endpoints:
             StatusCode.NOT_FOUND,
             headers
         );
-    });
-    
-    // Files endpoint with category and name
-    router.map_func("/files/", (context) => {
-        var components = context.request.path_components.to_vector();
-        
-        if (components.count() < 3) {
-            var headers = new Catalogue<string, string>();
-            headers.add("Content-Type", "application/json");
-            return new BufferedHttpResult.from_string(
-                @"{ \"error\": \"Category and filename required\" }",
-                StatusCode.BAD_REQUEST,
-                headers
-            );
-        }
-        
-        var category = components[1];
-        var name = components[2];
+    }
+}
+
+// Files handler - uses two named segments
+class FilesHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var category = route_context.get_segment("category");
+        var name = route_context.get_segment("name");
         
         // Simulated file lookup
-        var files = new Dictionary<string, Dictionary<string, File>>();
-        var docs = new Dictionary<string, File>();
-        docs.set("readme.txt", new File("readme.txt", "docs", "This is the readme file"));
-        docs.set("guide.pdf", new File("guide.pdf", "docs", "User guide"));
+        var files = new Dictionary<string, Dictionary<string, ExampleFile>>();
+        var docs = new Dictionary<string, ExampleFile>();
+        docs.set("readme.txt", new ExampleFile("readme.txt", "docs", "This is the readme file"));
+        docs.set("guide.pdf", new ExampleFile("guide.pdf", "docs", "User guide"));
         
-        var images = new Dictionary<string, File>();
-        images.set("logo.png", new File("logo.png", "images", "Company logo"));
-        images.set("banner.jpg", new File("banner.jpg", "images", "Website banner"));
+        var images = new Dictionary<string, ExampleFile>();
+        images.set("logo.png", new ExampleFile("logo.png", "images", "Company logo"));
+        images.set("banner.jpg", new ExampleFile("banner.jpg", "images", "Website banner"));
         
         files.set("docs", docs);
         files.set("images", images);
         
-        Dictionary<string, File>? category_files = null;
+        Dictionary<string, ExampleFile>? category_files = null;
         if (files.try_get(category, out category_files)) {
-            File? file = null;
+            ExampleFile? file = null;
             if (category_files.try_get(name, out file)) {
                 var headers = new Catalogue<string, string>();
                 headers.add("Content-Type", "application/json");
@@ -331,29 +255,55 @@ Available endpoints:
             StatusCode.NOT_FOUND,
             headers
         );
-    });
-    
-    // Path information endpoint - shows all path components
-    router.map_func("/pathinfo", (context) => {
+    }
+}
+
+// Path info handler
+class PathInfoHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         var parts = new Series<string>();
         parts.add("Path Information:\n");
-        parts.add(@"  Raw path: $(context.request.raw_path)\n");
-        parts.add(@"  Path components: $(context.request.path_components.count())\n");
+        parts.add(@"  Raw path: $(http_context.request.raw_path)\n");
+        parts.add(@"  Path components: $(http_context.request.path_components.count())\n");
         parts.add("\n  Components:\n");
         
-        context.request.path_components
+        http_context.request.path_components
             .with_positions()
             .iterate((pair) => {
                 parts.add(@"    [$((int)pair.position)]: $(pair.item)\n");
             });
         
-        parts.add(@"\n  Query string: $(context.request.query_string)\n");
+        parts.add(@"\n  Query string: $(http_context.request.query_string)\n");
+        
+        // Show named segments from route context
+        parts.add("\n  Named segments:\n");
+        route_context.named_segments.to_immutable_buffer()
+            .iterate((kv) => {
+                parts.add(@"    $(kv.key): $(kv.value)\n");
+            });
         
         var result = parts.to_immutable_buffer()
             .aggregate<string>("", (acc, s) => acc + s);
         
         return new BufferedHttpResult.from_string(result);
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8082, router);
+    
+    // Register routes with named segments
+    router.get("/", new RootHandler());
+    router.get("/hello", new HelloHandler());
+    router.get("/hello/{name}", new HelloNameHandler());
+    router.get("/users", new UsersHandler());
+    router.get("/users/{id}", new UserByIdHandler());
+    router.get("/users/{id}/posts", new UserPostsHandler());
+    router.get("/api/v1/status", new ApiStatusHandler());
+    router.get("/api/v1/items/{id}", new ApiItemHandler());
+    router.get("/files/{category}/{name}", new FilesHandler());
+    router.get("/pathinfo", new PathInfoHandler());
     
     print("Path Routing Example Server running on port 8082\n");
     print("Try these endpoints:\n");
@@ -424,12 +374,12 @@ class Item {
     }
 }
 
-class File {
+class ExampleFile {
     public string name { get; private set; }
     public string category { get; private set; }
     public string description { get; private set; }
     
-    public File(string name, string category, string description) {
+    public ExampleFile(string name, string category, string description) {
         this.name = name;
         this.category = category;
         this.description = description;

+ 53 - 35
examples/QueryParameters.vala

@@ -9,25 +9,25 @@ using Invercargill.DataStructures;
  * 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");
+
+// Greet handler - simple query parameter access
+class GreetHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var name = http_context.request.get_query_or_default("name", "World");
+        var greeting = http_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"));
+    }
+}
+
+// Search handler - multiple query parameters with validation
+class SearchHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var query = http_context.request.get_query("q");
+        var limit = int.parse(http_context.request.get_query_or_default("limit", "10"));
+        var offset = int.parse(http_context.request.get_query_or_default("offset", "0"));
         
         if (query == null || query == "") {
             var headers = new Catalogue<string, string>();
@@ -66,12 +66,14 @@ void main() {
             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");
+    }
+}
+
+// Debug handler - boolean flag query parameters
+class DebugHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var verbose = http_context.request.has_query("verbose");
+        var level = http_context.request.get_query_or_default("level", "info");
         
         var parts = new Series<string>();
         parts.add("Debug Information:\n");
@@ -80,7 +82,7 @@ void main() {
         
         // Add query parameters listing using Enumerable
         parts.add("\nAll query parameters:\n");
-        context.request.query_params.to_immutable_buffer()
+        http_context.request.query_params.to_immutable_buffer()
             .iterate((grouping) => {
                 grouping.iterate((value) => {
                     parts.add(@"  - $(grouping.key): $value\n");
@@ -91,11 +93,13 @@ void main() {
             .aggregate<string>("", (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");
+    }
+}
+
+// Filter handler - query parameter with multiple values (comma-separated)
+class FilterHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var tags_param = http_context.request.get_query("tags");
         
         if (tags_param == null) {
             var headers = new Catalogue<string, string>();
@@ -135,13 +139,15 @@ void main() {
             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"));
+    }
+}
+
+// Range handler - numeric query parameters with range validation
+class RangeHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
+        var min = int.parse(http_context.request.get_query_or_default("min", "0"));
+        var max = int.parse(http_context.request.get_query_or_default("max", "100"));
+        var step = int.parse(http_context.request.get_query_or_default("step", "1"));
         
         if (min >= max) {
             var headers = new Catalogue<string, string>();
@@ -179,7 +185,19 @@ void main() {
             StatusCode.OK,
             headers
         );
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8081, router);
+    
+    // Register routes
+    router.get("/greet", new GreetHandler());
+    router.get("/search", new SearchHandler());
+    router.get("/debug", new DebugHandler());
+    router.get("/filter", new FilterHandler());
+    router.get("/range", new RangeHandler());
     
     print("Query Parameters Example Server running on port 8081\n");
     print("Try these endpoints:\n");

+ 2 - 2
examples/RemoteAddress.vala

@@ -17,7 +17,7 @@ public class RemoteAddressExample : Object {
 
 // Simple handler that responds with client information
 public class SimpleHttpHandler : Object, RequestHandler {
-    public async HttpResult handle(HttpContext context) {
+    public async HttpResult handle_request(HttpContext context) throws Error {
         var request = context.request;
         
         // Access the remote address
@@ -38,7 +38,7 @@ public class SimpleHttpHandler : Object, RequestHandler {
         );
         
         // Log the request to console
-        print(@"[$(get_current_time())] $(request.method) $(request.raw_path) from $(remote_address ?? "unknown")");
+        print(@"[$(get_current_time())] $(request.method) $(request.raw_path) from $(remote_address ?? "unknown")\n");
         
         return response;
     }

+ 17 - 8
examples/SimpleApi.vala

@@ -2,21 +2,30 @@ using Astralis;
 using Invercargill;
 using Invercargill.DataStructures;
 
-void main() {
-    var router = new Router();
-    var server = new Server(8080, router);
-    
-    router.map_func("/hello", (context) => {
+// Simple handler for /hello endpoint
+class HelloHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         print("Handling /hello\n");
         return new BufferedHttpResult.from_string("Hello from Astralis!");
-    });
+    }
+}
 
-    router.map_func("/json", (context) => {
+// Simple handler for /json endpoint
+class JsonHandler : Object, RouteHandler {
+    public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
         print("Handling /json\n");
         var headers = new Catalogue<string, string>();
         headers.add("Content-Type", "application/json");
         return new BufferedHttpResult.from_string("{ \"message\": \"Hello JSON\" }", StatusCode.OK, headers);
-    });
+    }
+}
+
+void main() {
+    var router = new Router();
+    var server = new Server(8080, router);
+    
+    router.map("/hello", new HelloHandler());
+    router.map("/json", new JsonHandler());
 
     server.run();
 }