Sign in

    mars

    Hono-inspired HTTP framework for MoonBit

    http
    router
    web-framework
    Download zip
    Author
    Version
    0.2.3
    License
    MIT
    Last updated
    8 months ago
    Downloads
    6K

    #Mars

    A Hono-inspired HTTP framework for MoonBit.

    #Features

    • Trie-based Router: Fast URL matching with parameter extraction
    • Dynamic Parameters: Support for :id style URL parameters
    • Wildcard Routes: Support for * wildcard patterns
    • Optional Parameters: Support for :param? optional parameters
    • Regex Parameters: Support for :id{[0-9]+} regex-constrained parameters
    • HTTP Methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE
    • Middleware Support: Chain multiple handlers
    • JSON/HTML/Text Responses: Built-in response helpers

    #Installation

    Add to your moon.mod.json:

    { "deps": { "mizchi/mars": "0.1.0" } }

    #Usage

    async fn main {
    let app = @mars.Mars::new()

    // Static route
    let _ = app.get("/", @mars.handler(async fn(ctx) {
    ctx.text("Hello, Mars!")
    }))

    // Dynamic parameter
    let _ = app.get("/users/:id", @mars.handler(async fn(ctx) {
    let id = ctx.param("id").unwrap_or("unknown")
    ctx.json({ "id": id })
    }))

    // Wildcard
    let _ = app.get("/files/*", @mars.handler(async fn(ctx) {
    ctx.text("File path: " + ctx.path())
    }))

    // Multiple methods
    let _ = app.post("/users", @mars.handler(async fn(ctx) {
    ctx.json({ "status": "created" }, status=201)
    }))

    // Start server
    app.serve(@socket.Addr::parse("127.0.0.1:3000"))
    }

    #API

    #Mars

    • Mars::new() -> Mars - Create new application
    • Mars::get(path, handler) -> Mars - Register GET route
    • Mars::post(path, handler) -> Mars - Register POST route
    • Mars::put(path, handler) -> Mars - Register PUT route
    • Mars::delete(path, handler) -> Mars - Register DELETE route
    • Mars::patch(path, handler) -> Mars - Register PATCH route
    • Mars::all(path, handler) -> Mars - Register route for all methods
    • Mars::use_(middleware) -> Mars - Add middleware
    • Mars::serve(addr) - Start HTTP server

    #Context

    • Context::param(name) -> String? - Get URL parameter
    • Context::path() -> String - Get request path
    • Context::header(name) -> String? - Get request header
    • Context::text(body, status?) - Send text response
    • Context::json(data, status?) - Send JSON response
    • Context::html(body, status?) - Send HTML response
    • Context::redirect(url) - Send redirect response
    • Context::not_found() - Send 404 response

    #Router Patterns

    • /users - Static path
    • /users/:id - Dynamic parameter
    • /users/:id{[0-9]+} - Regex-constrained parameter
    • /files/* - Wildcard (matches any path)
    • /api/:type? - Optional parameter

    #License

    MIT

    Env

    pub(open) trait Env {
    get_var(Self, String) -> String?
    get_binding(Self, String) -> Json?
    }

    Environment trait for platform-specific bindings Implement this trait for your platform (Cloudflare, Deno, etc.)

    BackgroundTask

    pub(all) struct BackgroundTask {
    task : async () -> Unit
    name : String
    }

    Background task that will run after response is sent

    Context

    pub(all) struct Context {
    request :
    Request

    params :
    Params

    vars : Variables
    execution_ctx : ExecutionContext
    // private fields
    }

    HTTP Context for request/response handling

    Context::body

    async fn Context::body(self : Context) -> String

    Read request body as string (native implementation)

    Context::body_json

    async fn Context::body_json(self : Context) -> Json?

    Parse request body as JSON

    Context::conn

    Get server connection (native only)

    Context::cookie

    fn Context::cookie(self : Context, name : String) -> String?

    Get a cookie by name

    Context::cookies

    fn Context::cookies(self : Context) -> Map[String, String]

    Get all cookies
    fn Context::delete_cookie(self : Context, name : String) -> Unit

    Delete a cookie

    Context::end_response

    async fn Context::end_response(self : Context) -> Unit

    End the response (native implementation)

    Context::env_binding

    fn Context::env_binding(self : Context, name : String) -> Json?

    Get environment binding as JSON

    Context::env_var

    fn Context::env_var(self : Context, name : String) -> String?

    Get environment variable

    Context::get

    fn Context::get(self : Context, key : String) -> String?

    Get custom data

    Context::header

    fn Context::header(self : Context, name : String) -> String?

    Get a request header

    Context::html

    async fn Context::html(self : Context, body : String, status? : Int) -> Unit

    Send an HTML response (native implementation)

    Context::is_response_sent

    fn Context::is_response_sent(self : Context) -> Bool

    Check if response has been sent

    Context::json

    async fn Context::json(self : Context, data : Json, status? : Int) -> Unit

    Send a JSON response (native implementation)

    Context::meth

    Get request method

    Context::new

    Create a new Context (native-specific constructor)

    Context::not_found

    async fn Context::not_found(self : Context) -> Unit

    Send a 404 Not Found response (native implementation)

    Context::param

    fn Context::param(self : Context, name : String) -> String?

    Get a URL parameter by name

    Context::path

    fn Context::path(self : Context) -> String

    Get request path

    Context::queries

    fn Context::queries(self : Context) -> Map[String, String]

    Get all query parameters

    Context::query

    fn Context::query(self : Context, name : String) -> String?

    Get a query parameter by name

    Context::redirect

    async fn Context::redirect(self : Context, url : String) -> Unit

    Send a redirect response (native implementation)

    Context::set

    fn Context::set(self : Context, key : String, value : String) -> Unit

    Set custom data
    fn Context::set_cookie(self : Context, name : String, value : String, max_age? : Int, path? : String, http_only? : Bool, same_site? : String) -> Unit

    Set a cookie

    Context::set_header

    fn Context::set_header(self : Context, name : String, value : String) -> Unit

    Set a response header

    Context::set_status

    fn Context::set_status(self : Context, status : Int) -> Unit

    Set response status code

    Context::sse_start

    async fn Context::sse_start(self : Context) -> Unit

    Start an SSE response (native implementation)

    Context::text

    async fn Context::text(self : Context, body : String, status? : Int) -> Unit

    Send a text response (native implementation)

    Context::wait_until

    fn Context::wait_until(self : Context, task : async () -> Unit, name? : String) -> Unit

    Schedule a background task (like Cloudflare's waitUntil)

    Context::with_env

    Create a new Context with environment bindings (native-specific constructor)

    Context::write_raw

    async fn Context::write_raw(self : Context, data : String) -> Unit

    Write raw data to the response (native implementation)

    EmptyEnv

    pub(all) struct EmptyEnv {
    }

    Empty environment (no bindings)
    impl Env for EmptyEnv

    EmptyEnv::new

    fn EmptyEnv::new() -> EmptyEnv

    ExecutionContext

    pub(all) struct ExecutionContext {
    // private fields
    }

    ExecutionContext manages background tasks

    ExecutionContext::deactivate

    fn ExecutionContext::deactivate(self : ExecutionContext) -> Unit

    Deactivate context (no more tasks can be added)

    ExecutionContext::get_tasks

    Get all pending tasks (for testing)

    ExecutionContext::is_active

    fn ExecutionContext::is_active(self : ExecutionContext) -> Bool

    Check if context is still active

    ExecutionContext::new

    Create a new ExecutionContext

    ExecutionContext::pending_count

    fn ExecutionContext::pending_count(self : ExecutionContext) -> Int

    Get number of pending tasks

    ExecutionContext::run_tasks

    async fn ExecutionContext::run_tasks(self : ExecutionContext) -> Unit

    Execute all pending background tasks Called after response is sent

    ExecutionContext::wait_until

    fn ExecutionContext::wait_until(self : ExecutionContext, task : async () -> Unit, name? : String) -> Unit

    Schedule a background task to run after response is sent Similar to Cloudflare's ctx.waitUntil()

    Handler

    pub(all) type Handler async (Context) -> Unit

    Handler function signature Handler receives a Context and returns Unit

    Handler::inner

    #deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
    fn Handler::inner(self : Handler) -> (async (Context) -> Unit)
    Convert newtype to its underlying type, automatically derived.

    MapEnv

    pub(all) struct MapEnv {
    vars : Map[String, String]
    bindings : Map[String, Json]
    }

    Map-based environment (for testing and simple use cases)
    impl Env for MapEnv

    MapEnv::new

    fn MapEnv::new() -> MapEnv

    MapEnv::with_binding

    fn MapEnv::with_binding(self : MapEnv, name : String, value : Json) -> MapEnv

    MapEnv::with_var

    fn MapEnv::with_var(self : MapEnv, name : String, value : String) -> MapEnv

    Mars

    pub(all) struct Mars {
    router :
    TrieRouter

    handlers : Array[Handler]
    middlewares : Array[Handler]
    }

    Mars HTTP Framework A Hono-inspired HTTP framework for MoonBit

    Mars::all

    fn Mars::all(self : Mars, path : String, handler : Handler) -> Mars

    Register a route for all HTTP methods

    Mars::delete

    fn Mars::delete(self : Mars, path : String, handler : Handler) -> Mars

    Register a DELETE route

    Mars::get

    fn Mars::get(self : Mars, path : String, handler : Handler) -> Mars

    Register a GET route

    Mars::new

    fn Mars::new() -> Mars

    Create a new Mars application

    Mars::patch

    fn Mars::patch(self : Mars, path : String, handler : Handler) -> Mars

    Register a PATCH route

    Mars::post

    fn Mars::post(self : Mars, path : String, handler : Handler) -> Mars

    Register a POST route

    Mars::put

    fn Mars::put(self : Mars, path : String, handler : Handler) -> Mars

    Register a PUT route

    Mars::query

    fn Mars::query(self : Mars, path : String, handler : Handler) -> Mars

    Register a QUERY route (RFC 9110)

    Mars::serve

    async fn Mars::serve(self : Mars, addr :
    Addr
    ) -> Unit

    Start the HTTP server (native only)

    Mars::serve_with_env

    async fn Mars::serve_with_env(self : Mars, addr :
    Addr
    , env : MapEnv) -> Unit

    Start the HTTP server with environment bindings (native only)

    Mars::use_

    fn Mars::use_(self : Mars, handler : Handler) -> Mars

    Add a middleware to the application

    PlatformContext

    Native platform-specific context data

    PlatformContext::new

    Create a new PlatformContext for native

    Variables

    pub(all) struct Variables {
    data : Map[String, Json]
    }

    Typed variables storage Uses Json for flexible storage with runtime type checking

    Variables::get_bool

    fn Variables::get_bool(self : Variables, key : String) -> Bool?

    Get a boolean variable

    Variables::get_json

    fn Variables::get_json(self : Variables, key : String) -> Json?

    Get a JSON variable

    Variables::get_number

    fn Variables::get_number(self : Variables, key : String) -> Double?

    Get a number variable

    Variables::get_string

    fn Variables::get_string(self : Variables, key : String) -> String?

    Get a string variable

    Variables::has

    fn Variables::has(self : Variables, key : String) -> Bool

    Check if variable exists

    Variables::keys

    fn Variables::keys(self : Variables) -> Array[String]

    Get all keys

    Variables::new

    fn Variables::new() -> Variables

    Variables::remove

    fn Variables::remove(self : Variables, key : String) -> Unit

    Remove a variable

    Variables::set_bool

    fn Variables::set_bool(self : Variables, key : String, value : Bool) -> Unit

    Set a boolean variable

    Variables::set_json

    fn Variables::set_json(self : Variables, key : String, value : Json) -> Unit

    Set a JSON variable

    Variables::set_number

    fn Variables::set_number(self : Variables, key : String, value : Double) -> Unit

    Set a number variable

    Variables::set_string

    fn Variables::set_string(self : Variables, key : String, value : String) -> Unit

    Set a string variable

    compose

    fn compose(handlers : Array[Handler]) -> Handler

    Compose multiple handlers into a chain Each handler is called in order

    handler

    fn handler(f : async (Context) -> Unit) -> Handler

    Helper to create a Handler from an async function

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io