8000 GitHub - MuntasirSZN/fetchttp: `fetch` Web API Implementation In Rust!
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

MuntasirSZN/fetchttp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

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

Repository files navigation

fetchttp

Crates.io Documentation License: MIT CI

A WHATWG Fetch API compliant HTTP client library for Rust that provides the familiar fetch() interface you know and love from web development.

✨ Features

  • 🌐 WHATWG Fetch API Compliant - Follows the official specification
  • πŸš€ Async/Await Support - Built on Tokio for modern async Rust
  • πŸ”’ Type Safety - Leverages Rust's type system for safe HTTP operations
  • πŸ“¦ JSON Support - Built-in JSON serialization/deserialization with serde
  • πŸ”§ Flexible Bodies - Support for text, bytes, and JSON request/response bodies
  • πŸ“‹ Header Management - Complete header manipulation API
  • πŸ”„ Request/Response Cloning - Efficient cloning following the specification
  • ⏹️ Abort Signals - Request cancellation support
  • πŸ”— Connection Pooling - Automatic connection reuse for better performance

πŸš€ Quick Start

Add fetchttp to your Cargo.toml:

[dependencies]
fetchttp = "1.0.0"
tokio = { version = "1.0", features = ["full"] }
serde_json = "1.0"  # For JSON support

Simple GET Request

use fetchttp::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let response = fetch("https://api.github.com/users/octocat", None).await?;
    
    if response.ok() {
        let user: serde_json::Value = response.json().await?;
        println!("User: {}", user["name"]);
    }
    
    Ok(())
}

POST Request with JSON

use fetchttp::*;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = json!({
        "name": "John Doe",
        "email": "john@example.com"
    });
    
    let mut init = RequestInit::new();
    init.method = Some("POST".to_string());
    init.body = Some(ReadableStream::from_json(&data));
    
    let response = fetch("https://api.example.com/users", Some(init)).await?;
    
    if response.ok() {
        println!("User created successfully!");
    }
    
    Ok(())
}

Custom Headers

use fetchttp::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut headers = Headers::new();
    headers.set("Authorization", "Bearer your-token")?;
    headers.set("User-Agent", "MyApp/1.0")?;
    
    let mut init = RequestInit::new();
    init.headers = Some(headers);
    
    let response = fetch("https://api.example.com/protected", Some(init)).await?;
    let text = response.text().await?;
    
    println!("Response: {}", text);
    Ok(())
}

Request Cancellation

use fetchttp::*;
use std::time::Duration;
use tokio::time::sleep;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let controller = AbortController::new();
    let signal = controller.signal().clone();
    
    let mut init = RequestInit::new();
    init.signal = Some(signal);
    
    // Cancel the request after 1 second
    tokio::spawn(async move {
        sleep(Duration::from_secs(1)).await;
        controller.abort();
    });
    
    match fetch("https://httpbin.org/delay/5", Some(init)).await {
        Ok(response) => println!("Request completed: {}", response.status()),
        Err(FetchError::Abort(_)) => println!("Request was cancelled"),
        Err(e) => println!("Request failed: {}", e),
    }
    
    Ok(())
}

πŸ“š API Reference

Core Functions

  • fetch(url, init) - Perform an HTTP request

Request Types

  • Request - Represents an HTTP request
  • RequestInit - Configuration for requests
  • RequestMode - CORS mode settings
  • RequestCredentials - Credential handling
  • RequestCache - Cache control
  • RequestRedirect - Redirect handling

Response Types

  • Response - Represents an HTTP response
  • ResponseInit - Configuration for responses
  • ResponseType - Response type information

Body and Streams

  • ReadableStream - Request/response body handling
  • Headers - HTTP header management

Error Handling

  • FetchError - Main error type
  • TypeError - Type validation errors
  • NetworkError - Network-related errors
  • AbortError - Request cancellation errors

Abort Support

  • AbortController - Controls request cancellation
  • AbortSignal - Signals request cancellation

πŸ”„ Body Consumption

Response and request bodies can be consumed in multiple ways:

// Text
let text = response.text().await?;

// JSON  
let data: MyStruct = response.json().await?;

// Bytes
let bytes = response.array_buffer().await?;

// Blob (alias for array_buffer)
let blob = response.blob().await?;

πŸ›‘οΈ Error Handling

The library provides comprehensive error handling:

match fetch("https://example.com", None).await {
    Ok(response) => {
        if response.ok() {
            println!("Success: {}", response.status());
        } else {
            println!("HTTP Error: {}", response.status());
        }
    }
    Err(FetchError::Type(e)) => {
        eprintln!("Type error: {}", e);
    }
    Err(FetchError::Network(e)) => {
        eprintln!("Network error: {}", e);
    }
    Err(FetchError::Abort(e)) => {
        eprintln!("Request aborted: {}", e);
    }
}

πŸ”§ Advanced Usage

Custom HTTP Methods

let mut init = RequestInit::new();
init.method = Some("PATCH".to_string());
init.body = Some(ReadableStream::from_json(&data));

let response = fetch("https://api.example.com/resource/1", Some(init)).await?;

File Upload

use std::fs;

let file_content = fs::read("document.pdf")?;

let mut init = RequestInit::new();
init.method = Some("POST".to_string());
init.body = Some(ReadableStream::from_bytes(file_content.into()));

let response = fetch("https://api.example.com/upload", Some(init)).await?;

Response Headers

let response = fetch("https://httpbin.org/response-headers", None).await?;

for (name, value) in response.headers().entries() {
    println!("{}: {}", name, value);
}

// Check specific header
if let Some(content_type) = response.headers().get("content-type")? {
    println!("Content-Type: {}", content_type);
}

πŸ—οΈ Building and Testing

# Build the library
cargo build

# Run tests
cargo test

# Run benchmarks
cargo bench

# Generate documentation
cargo doc --open

πŸ“Š Performance

The library is designed for performance with:

  • Connection pooling via hyper
  • Efficient body streaming
  • Zero-copy operations where possible
  • Minimal allocations

See benches/ for detailed performance benchmarks.

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

πŸ“„ License

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

🌟 Comparison with Other Libraries

Feature fetchttp reqwest hyper ureq
WHATWG Fetch API βœ… ❌ ❌ ❌
Async/Await βœ… βœ… βœ… ❌
JSON Support βœ… βœ… ❌ βœ…
Connection Pooling βœ… βœ… βœ… ❌
Abort Signals βœ… βœ… ❌ ❌
Web API Compatibility βœ… ❌ ❌ ❌

πŸ”— Links


Made with ❀️ by MuntasirSZN

About

`fetch` Web API Implementation In Rust!

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 2

  •  
  •  

Languages

0