summaryrefslogtreecommitdiff
path: root/litedb/router.ml
diff options
context:
space:
mode:
Diffstat (limited to 'litedb/router.ml')
-rw-r--r--litedb/router.ml73
1 files changed, 73 insertions, 0 deletions
diff --git a/litedb/router.ml b/litedb/router.ml
new file mode 100644
index 0000000..ef9d5c5
--- /dev/null
+++ b/litedb/router.ml
@@ -0,0 +1,73 @@
+(* Import the StdLabels module which provides labeled versions of standard library functions *)
+open StdLabels
+(* Import the Routes library for type-safe HTTP routing *)
+open Routes
+(* Import Piaf for HTTP types like Method.t *)
+open Piaf
+
+(* Create a custom Map module keyed by HTTP methods (GET, POST, etc.) *)
+(* This allows us to organize routes by their HTTP verb *)
+module R = Map.Make (struct
+ (* The key type is Piaf's Method.t (represents HTTP methods) *)
+ type t = Method.t
+
+ (* Define how to compare two HTTP methods for ordering in the map *)
+ let compare a b =
+ (* Convert methods to strings (e.g., "GET", "POST") *)
+ let a_str = Method.to_string a in
+ let b_str = Method.to_string b in
+ (* Use standard string comparison *)
+ String.compare a_str b_str
+ ;;
+ end)
+
+(* Define all routes in the application *)
+let routes =
+ (* Use fold_left to build up a map of routes *)
+ List.fold_left
+ (* For each (verb, route) pair, add the route to the map under that verb *)
+ ~f:(fun acc (v, r) -> R.add_to_list v r acc)
+ (* Start with an empty map *)
+ ~init:R.empty
+ (* List of (HTTP method, route pattern -> handler) tuples *)
+ [ `GET, (s "posts" /? nil) @--> Handler.get_posts
+ (* `GET - HTTP GET method *)
+ (* s "posts" - matches the literal string "posts" *)
+ (* /? - path concatenation operator *)
+ (* nil - end of path (no more segments) *)
+ (* @--> - binds the route pattern to the handler function *)
+ (* Handler.get_posts - the function that handles this route *)
+ ; `GET, (s "posts" / int /? nil) @--> Handler.get_post
+ (* / int - captures an integer parameter (post ID) *)
+ ; `GET, (s "comments" / int /? nil) @--> Handler.get_comment
+ (* Get a single comment by ID *)
+ ; `GET, (s "users" / str / s "comments" /? nil) @--> Handler.get_user_comments
+ (* / str - captures a string parameter (username) *)
+ ; `GET, (s "posts" / int / s "comments" /? nil) @--> Handler.get_post_comments
+ (* Get all comments for a specific post *)
+ ; `GET, (s "comments" / int / s "children" /? nil) @--> Handler.get_comment_children
+ (* Get child comments (replies) for a comment *)
+ ]
+;;
+
+(* Transform the routes map by applying 'one_of' to each list of routes *)
+(* 'one_of' combines multiple routes into a single router that tries each in order *)
+let router = R.map one_of routes
+
+(* Function to match an incoming request against our routes *)
+let match_route verb path =
+ (* Try to find routes for the given HTTP verb in our map *)
+ match R.find_opt verb router with
+ (* If we have routes for this verb, try to match the path *)
+ | Some router ->
+ (* Use the Routes library's match' function to find a matching route *)
+ (match match' router ~target:path with
+ (* Exact match - the path matches completely *)
+ | FullMatch r -> Some r
+ (* Match with trailing slash - e.g., "/posts" matches "/posts/" *)
+ | MatchWithTrailingSlash r -> Some r
+ (* No routes matched the path *)
+ | NoMatch -> None)
+ (* We don't have any routes for this HTTP verb *)
+ | None -> None
+;;