| Crates.io | klbfw |
| lib.rs | klbfw |
| version | 0.1.0 |
| created_at | 2025-11-12 11:37:54.750217+00 |
| updated_at | 2025-11-12 11:37:54.750217+00 |
| description | Comprehensive REST API client with OAuth2, API key authentication, and file upload support |
| homepage | https://github.com/KarpelesLab/klbfw-rs |
| repository | https://github.com/KarpelesLab/klbfw-rs |
| max_upload_size | |
| id | 1929162 |
| size | 131,728 |
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.
Add this to your Cargo.toml:
[dependencies]
klbfw = "0.1"
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(())
}
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!({}))?;
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!({}))?;
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);
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:
Based on the Go version (~/projects/rest):
apply() - Makes REST API request and unmarshals responsedo_request() - Executes request and returns raw ResponseTime - Custom time type with JSON serialization matching API formatResponse - REST API response with standard fieldsParam - Convenience type for parametersRestError - Comprehensive error type with conversion to std errorsToken - OAuth2 token with automatic renewalApiKey - API key with Ed25519 signingBlocking vs Async: This Rust version currently implements a blocking client using reqwest::blocking. The Go version uses standard http.Client which is also blocking.
Context: Instead of Go's context.Context, this version uses RestContext which holds the client configuration and authentication.
Error Handling: Uses Rust's Result type and thiserror for error handling, with conversions to standard error types.
Generics: The Rust version uses generics for type-safe response parsing, similar to the Go version's generic As function.
Run unit tests with:
cargo test --lib
All unit tests pass successfully (15 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:
See tests/README.md for more details.
MIT
This is a direct port of the Go library from ~/projects/rest. Key features implemented:
apply, do_request)The implementation maintains compatibility with the existing API while following Rust idioms and best practices.