diff options
Diffstat (limited to 'litedb/router.ml')
-rw-r--r-- | litedb/router.ml | 73 |
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 +;; |