Skip to content

oboard/mio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

oboard/mio

A powerful and modern HTTP networking library for MoonBit with multi-backend support.

Version License

Features

  • πŸš€ Async/Await Support: Built-in async operations with @mio.run
  • 🌐 Complete HTTP Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD, CONNECT, TRACE
  • πŸ“„ JSON Handling: Seamless JSON parsing and response handling
  • πŸ“ File Downloads: Built-in file download capabilities with custom save paths
  • 🎯 Multi-Backend: Support for Native (libcurl), JavaScript (Fetch API), and WASM
  • ⚑ Type Safety: Full MoonBit type system support with error handling
  • πŸ”§ Flexible Options: Headers, credentials, modes, and request customization

Backend Support

Native Backend (native, llvm)

  • HTTP Engine: libcurl for robust HTTP requests
  • Features: All HTTP methods, file downloads, full header support
  • Dependencies: Requires libcurl system library
  • Performance: Optimized for server-side and native applications

JavaScript Backend (js)

  • HTTP Engine: Fetch API
  • Features: Browser and Node.js compatibility
  • Dependencies: No external dependencies
  • Performance: Optimized for web applications and frontend development

WebAssembly Backend (wasm, wasm-gc)

  • HTTP Engine: WASM-compatible implementation
  • Features: Cross-platform WebAssembly support
  • Dependencies: WASM runtime environment
  • Performance: Optimized for WASM applications

Installation

Add to your moon.mod.json:

{
  "deps": {
    "oboard/mio": "0.3.0"
  }
}

Quick Start

Basic GET Request

@mio.run(fn() {
  match (try? @mio.get("https://api.github.com")) {
    Ok(response) => {
      println("Status: " + response.statusCode.to_string())
      println("Response: " + response.text())
    }
    Err(e) => println("Error: " + e.to_string())
  }
})

POST Request with JSON Data

@mio.run(fn() {
  match (try? @mio.post("https://httpbin.org/post", 
    data={ 
      "name": "MoonBit", 
      "version": "0.3.0",
      "features": ["async", "http", "json"]
    })) {
    Ok(response) => {
      println("Posted successfully!")
      println(response.unwrap_json())
    }
    Err(e) => println("Failed: " + e.to_string())
  }
})

Custom Headers and Options

@mio.run(fn() {
  let headers = {
    "Authorization": "Bearer your-token",
    "User-Agent": "MoonBit-App/1.0",
    "Accept": "application/json"
  }
  
  match (try? @mio.get("https://api.example.com/data", 
    headers=headers,
    credentials=SameOrigin,
    mode=CORS)) {
    Ok(response) => {
      if response.statusCode == 200 {
        let data = response.json()
        // Process your data
      }
    }
    Err(e) => println("Request failed: " + e.to_string())
  }
})

File Download

@mio.run(fn() {
  // Download with custom filename
  match (try? @mio.download("https://api.github.com/repos/moonbitlang/core",
    save_path="github_repo.json")) {
    Ok(_) => println("File downloaded successfully!")
    Err(e) => println("Download failed: " + e.to_string())
  }
  
  // Download with dynamic filename based on headers
  match (try? @mio.download("https://example.com/file.zip",
    save_path_fn=fn(headers) {
      match headers.get("content-disposition") {
        Some(disposition) => extract_filename(disposition)
        None => "downloaded_file.zip"
      }
    })) {
    Ok(_) => println("File downloaded with dynamic name!")
    Err(e) => println("Download failed: " + e.to_string())
  }
})

API Reference

HTTP Methods

All HTTP methods support the same optional parameters:

  • headers?: Map[String, String] - Custom HTTP headers
  • credentials?: FetchCredentials - Request credentials (Omit, SameOrigin, Include)
  • mode?: FetchMode - Request mode (CORS, NoCORS, SameOrigin, Navigate)
// GET request
(try? @mio.get(url, headers?, credentials?, mode?))

// POST request with body or JSON data
(try? @mio.post(url, body?, data?, headers?, credentials?, mode?))

// Other HTTP methods
(try? @mio.put(url, body?, headers?, credentials?, mode?))
(try? @mio.delete(url, body?, headers?, credentials?, mode?))
(try? @mio.patch(url, body?, headers?, credentials?, mode?))
(try? @mio.options(url, body?, headers?, credentials?, mode?))
(try? @mio.head(url, body?, headers?, credentials?, mode?))
(try? @mio.connect(url, body?, headers?, credentials?, mode?))
(try? @mio.trace(url, body?, headers?, credentials?, mode?))

Response Handling

// HttpResponse methods
response.text()          // Get response as string
response.json()          // Parse JSON (may raise ParseError)
response.unwrap_json()   // Safe JSON parsing (returns Json::null() on error)
response.statusCode      // HTTP status code
response.headers         // Response headers as Map[String, String]
response.data           // Raw response data as Bytes

Error Handling

The library defines three main error types:

  • IOError - File system and I/O related errors
  • NetworkError - Network and HTTP request errors
  • ExecError - Execution and runtime errors

Advanced Usage

Custom Request with Full Control

@mio.run(fn() {
  match (try? @mio.request("https://api.example.com/upload",
    http_method=POST,
    body="custom request body",
    headers={
      "Content-Type": "text/plain",
      "X-Custom-Header": "value"
    },
    credentials=Include,
    mode=CORS)) {
    Ok(response) => {
      // Handle response
    }
    Err(NetworkError) => {
      // Handle network errors
    }
  }
})

Buffer Requests for Binary Data

@mio.run(fn() {
  match (try? @mio.request_buffer("https://example.com/image.png")) {
    Ok(response) => {
      // response.data contains raw bytes
      @fs.write_bytes_to_file("image.png", response.data)
    }
    Err(e) => println("Failed to download image")
  }
})

Examples

Check out these real-world projects using mio:

  • weatherquery - Weather query tool for Chinese locations
    • Fetches real-time weather data from APIs
    • Supports provinces, cities, and districts
    • Cross-platform (native and web)

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Links

About

A powerful HTTP networking package for MoonBit.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published