A high-performance HTTP router for MoonBit, inspired by julienschmidt/httprouter
# Verify installation
moon versionmoon add paveg/httprouter# Build the project
moon build
# Run tests
moon test
# Format code
moon fmt
# Check for errors without building
moon checkRouter
โโโ RadixTree
โโโ Node (root)
โโโ Node (Static: "users")
โ โโโ Node (Static: "me") โ GET handler
โ โโโ Node (Param: "id") โ GET, POST handlers
โโโ Node (Static: "files")
โโโ Node (Wildcard: "path") โ GET handlerlet router = @lib.Router::new()
router.get("/", fn(_ctx) { @lib.Response::text("Hello, World!") })
router.get("/users/:id", fn(ctx) {
match ctx.param("id") {
Some(id) => @lib.Response::json("{\"id\": \"" + id + "\"}")
None => @lib.Response::not_found()
}
})
router.post("/users", fn(ctx) {
@lib.Response::json("{\"created\": true}", status=201)
})// Matches /users/123, /users/abc, etc.
router.get("/users/:id", fn(ctx) {
let id = ctx.param("id") // Some("123")
// ...
})
// Multiple parameters
router.get("/users/:userId/posts/:postId", fn(ctx) {
let user_id = ctx.param("userId")
let post_id = ctx.param("postId")
// ...
})// Matches /files/a/b/c.txt -> path = "a/b/c.txt"
router.get("/files/*path", fn(ctx) {
let path = ctx.param("path") // Some("a/b/c.txt")
// ...
})router.get("/users/:id", fn(_ctx) { @lib.Response::text("param") })
router.get("/users/me", fn(_ctx) { @lib.Response::text("static") })
// GET /users/me -> "static"
// GET /users/123 -> "param"router.set_not_found(fn(_ctx) {
@lib.Response::json("{\"error\": \"Not Found\"}", status=404)
})
router.set_method_not_allowed(fn(allowed) {
let methods = allowed.map(fn(m) { m.to_string() }).join(", ")
@lib.Response::text("Allowed: " + methods, status=405)
})// Add global middleware
router.add_middleware(fn(ctx) {
// Return Some(ctx) to continue, None to short-circuit
if ctx.header("Authorization") is Some(_) {
Some(ctx)
} else {
None // Returns 403 Forbidden
}
})let router = @lib.Router::from_routes([
(@lib.Get, "/", fn(_ctx) { @lib.Response::text("home") }),
(@lib.Get, "/about", fn(_ctx) { @lib.Response::text("about") }),
(@lib.Post, "/api/users", fn(_ctx) { @lib.Response::json("{}") }),
])let router = @lib.Router::new()
router.get("/hello", fn(_ctx) { @lib.Response::text("Hello!") })
// Handle Fetch API request
let request = @lib.FetchRequest::new(
"GET",
"https://example.com/hello?name=world",
headers=[("Accept", "text/plain")],
)
let response = router.fetch(request)
// response.status = 200
// response.body = "Hello!"@lib.Response::text("Hello") // 200 text/plain
@lib.Response::text("Error", status=500) // 500 text/plain
@lib.Response::json("{\"ok\":true}") // 200 application/json
@lib.Response::html("<h1>Hello</h1>") // 200 text/html
@lib.Response::redirect("/new-location") // 302 redirect
@lib.Response::redirect("/new", status=301) // 301 permanent redirect
@lib.Response::not_found() // 404
@lib.Response::method_not_allowed([Get, Post]) // 405 with Allow header| Type | Description |
|---|---|
| Router | HTTP router with route registration and request handling |
| Context | Request context with path, params, headers, body |
| Response | HTTP response with status, headers, body |
| Method | HTTP method enum (Get, Post, Put, Delete, Patch, Head, Options) |
| Params | Collection of path parameters |
| FetchRequest | Fetch API compatible request |
| FetchResponse | Fetch API compatible response |
| Method | Description |
|---|---|
| Router::new() | Create a new router |
| Router::from_routes(routes) | Create router from route array |
| router.get(path, handler) | Register GET route |
| router.post(path, handler) | Register POST route |
| router.put(path, handler) | Register PUT route |
| router.delete(path, handler) | Register DELETE route |
| router.patch(path, handler) | Register PATCH route |
| router.head(path, handler) | Register HEAD route |
| router.options(path, handler) | Register OPTIONS route |
| router.handle(method, path, handler) | Register route with any method |
| router.serve(ctx) | Handle a request and return response |
| router.fetch(request) | Handle a FetchRequest and return FetchResponse |
| router.set_not_found(handler) | Set custom 404 handler |
| router.set_method_not_allowed(handler) | Set custom 405 handler |
| router.add_middleware(mw) | Add global middleware |
Install
Download zipA high-performance HTTP router for MoonBit, inspired by julienschmidt/httprouter