klbfw

Crates.ioklbfw
lib.rsklbfw
version0.1.0
created_at2025-11-12 11:37:54.750217+00
updated_at2025-11-12 11:37:54.750217+00
descriptionComprehensive REST API client with OAuth2, API key authentication, and file upload support
homepagehttps://github.com/KarpelesLab/klbfw-rs
repositoryhttps://github.com/KarpelesLab/klbfw-rs
max_upload_size
id1929162
size131,728
Mark Karpelès (MagicalTux)

documentation

https://docs.rs/klbfw

README

klbfw-rs

A Rust implementation of the KarpelesLab REST Framework client library.

This library provides a comprehensive client for interacting with RESTful API services, featuring authentication, token renewal, and response parsing.

Features

  • Simple API: Easy-to-use methods for RESTful requests with JSON encoding/decoding
  • Multiple Authentication Methods:
    • OAuth2 token management with automatic renewal
    • API key authentication with secure Ed25519 request signing
  • Robust Error Handling: Detailed error types with conversion to Rust standard error types
  • Custom Time Type: Handles API timestamps with microsecond precision
  • Response Parsing: Path-based value access in responses
  • File Upload Support:
    • Direct PUT uploads for small files
    • Multipart uploads for medium files
    • AWS S3 multipart uploads for large files (with automatic part size calculation)
    • Progress tracking callbacks
    • Parallel upload support
  • Blocking HTTP Client: Built on reqwest with connection pooling and timeouts

Installation

Add this to your Cargo.toml:

[dependencies]
klbfw = "0.1"

Usage

Basic Request

use klbfw::RestContext;
use serde::Deserialize;

#[derive(Deserialize)]
struct User {
    id: String,
    name: String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a REST context
    let ctx = RestContext::new();

    // Make a simple GET request
    let user: User = ctx.apply("Users/Get", "GET", serde_json::json!({
        "userId": "123"
    }))?;

    println!("User: {} ({})", user.name, user.id);
    Ok(())
}

Token Authentication

use klbfw::{RestContext, Token};

let token = Token::new(
    "access_token".to_string(),
    "refresh_token".to_string(),
    "client_id".to_string(),
    3600,
);

let ctx = RestContext::new().with_token(token);

// Make authenticated requests
let response = ctx.do_request("Protected/Resource", "GET", serde_json::json!({}))?;

API Key Authentication

use klbfw::{RestContext, ApiKey};

let api_key = ApiKey::new(
    "key-12345".to_string(),
    "base64_encoded_secret",
)?;

let ctx = RestContext::new().with_api_key(api_key);

// Requests are automatically signed
let response = ctx.do_request("Protected/Resource", "GET", serde_json::json!({}))?;

Custom Configuration

use klbfw::{RestContext, Config};

let config = Config::new(
    "https".to_string(),
    "api.example.com".to_string(),
).with_debug(true);

let ctx = RestContext::with_config(config);

File Upload

use klbfw::{upload, RestContext};
use std::fs::File;
use std::collections::HashMap;

let ctx = RestContext::new();
let file = File::open("largefile.dat")?;

// Upload with progress tracking
let response = upload(
    &ctx,
    "Files/Upload",
    "POST",
    HashMap::new(),
    file,
    "application/octet-stream",
    Some(Box::new(|bytes| {
        println!("Uploaded {} bytes", bytes);
    })),
)?;

The library automatically chooses the best upload method:

  • Direct PUT: For files < 5GB with known size
  • Multipart Upload: For medium files when server provides blocksize
  • AWS S3 Multipart: For large files (>64MB) with automatic part size calculation

Implemented Features

Based on the Go version (~/projects/rest):

Core API Methods

  • apply() - Makes REST API request and unmarshals response
  • do_request() - Executes request and returns raw Response

Type System

  • Time - Custom time type with JSON serialization matching API format
  • Response - REST API response with standard fields
  • Param - Convenience type for parameters
  • RestError - Comprehensive error type with conversion to std errors

Authentication

  • Token - OAuth2 token with automatic renewal
  • ApiKey - API key with Ed25519 signing

HTTP Client

  • ✅ Configurable HTTP client with connection pooling
  • ✅ Request/response handling
  • ✅ Error parsing and handling

File Upload

  • ✅ Direct PUT upload for small files
  • ✅ Multipart/chunked upload
  • ✅ AWS S3 multipart upload for large files
  • ✅ Progress tracking callbacks
  • ✅ Parallel upload support
  • ✅ Automatic upload method selection

Differences from Go Version

  1. Blocking vs Async: This Rust version currently implements a blocking client using reqwest::blocking. The Go version uses standard http.Client which is also blocking.

  2. Context: Instead of Go's context.Context, this version uses RestContext which holds the client configuration and authentication.

  3. Error Handling: Uses Rust's Result type and thiserror for error handling, with conversions to standard error types.

  4. Generics: The Rust version uses generics for type-safe response parsing, similar to the Go version's generic As function.

Testing

Unit Tests

Run unit tests with:

cargo test --lib

All unit tests pass successfully (15 tests).

Integration Tests

Integration tests use actual API endpoints (Misc/Debug:*) and are marked with #[ignore] by default.

To run all integration tests:

cargo test --tests -- --ignored

To run specific test suites:

# Run only REST API tests (8 tests)
cargo test --test integration_tests -- --ignored

# Run only upload tests (6 tests)
cargo test --test upload_tests -- --ignored

Integration tests verify:

  • REST API calls with various endpoints
  • Error handling and unwrapping
  • Parameter passing and response parsing
  • File uploads (empty, small, large files)
  • Upload progress tracking
  • SHA256 verification of uploaded files

See tests/README.md for more details.

License

MIT

Port Notes

This is a direct port of the Go library from ~/projects/rest. Key features implemented:

  • Base API access methods (apply, do_request)
  • Time type with custom JSON serialization/deserialization
  • Response type with all standard fields
  • Error types matching Go implementation
  • Token and API key authentication
  • HTTP client configuration
  • File upload with multiple strategies (PUT, multipart, AWS S3)
  • Progress tracking and parallel uploads

The implementation maintains compatibility with the existing API while following Rust idioms and best practices.

Commit count: 0

cargo fmt