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
- π― 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())
}
})
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?))
// 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
The 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.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")
}
})
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.