A powerful and modern HTTP networking library for MoonBit with multi-backend support.
- 🚀 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
- 🌊 Stream Processing: Real-time data streaming with callback support
- 📦 Binary Data Support: Native handling of binary data with unified
Bytesinterface across all backends - 🎯 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
- 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
- HTTP Engine: Fetch API
- Features: Browser and Node.js compatibility
- Dependencies: No external dependencies
- Performance: Optimized for web applications and frontend development
- HTTP Engine: WASM-compatible implementation
- Features: Cross-platform WebAssembly support
- Dependencies: WASM runtime environment
- Performance: Optimized for WASM applications
Add to your moon.mod.json:
{
"deps": {
"oboard/mio": "0.3.0"
}
}@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())
}
})@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())
}
})@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())
}
})@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())
}
})@mio.run(fn() {
// Stream processing with real-time data handling
let chunks = []
match (try? @mio.get_stream("https://api.example.com/stream",
fn(chunk) {
println("Received chunk: " + chunk)
chunks.push(chunk)
// Process each chunk as it arrives
})) {
Ok(response) => {
println("Stream completed with status: " + response.statusCode.to_string())
println("Total chunks received: " + chunks.length().to_string())
}
Err(e) => println("Stream failed: " + e.to_string())
}
})Note: Stream functionality is currently under development for native backend due to callback compatibility issues between MoonBit and C function pointers. It works properly on JavaScript and WASM backends.
All HTTP methods support the same optional parameters:
headers?: Map[String, String]- Custom HTTP headerscredentials?: 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?))
// Stream request with callback for real-time data processing
(try? @mio.get_stream(url, callback, headers?, credentials?, mode?))// 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 BytesThe library defines three main error types:
IOError- File system and I/O related errorsNetworkError- Network and HTTP request errorsExecError- Execution and runtime errors
@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
}
}
})Mio provides unified binary data support across all backends through the Bytes interface. All HTTP responses contain raw binary data in response.data, which can be processed as text or kept as binary.
@mio.run(fn() {
// All requests return binary data in response.data
match (try? @mio.get("https://example.com/image.png")) {
Ok(response) => {
// response.data contains raw bytes (unified across all backends)
@fs.write_bytes_to_file("image.png", response.data)
// For text content, use response.text()
let text_content = response.text()
println("Content: " + text_content)
}
Err(e) => println("Failed to download: " + e.to_string())
}
})
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)
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.