serverless-fn 0.1.0

A Rust library for simplifying serverless function development and invocation
Documentation

Serverless Function Library

Crates.io Documentation License: MIT

一个用于简化 Serverless 函数开发和调用的 Rust 库。核心设计理念是让调用 Serverless 函数如同调用普通函数一样简单,通过 Feature 标志灵活控制函数的调用方式(远程调用或本地调用)。

目录

功能特点

  • 🎯 简化调用接口 - 提供与普通函数相同的调用语法,隐藏底层网络通信、序列化等复杂性
  • 🚀 智能部署策略 - 根据 Feature 标志自动选择部署方式,支持远程调用和本地调用
  • 🔧 本地调试友好 - 在本地环境中无需实际部署即可测试
  • 🔒 类型安全 - 使用 Rust 的类型系统确保参数和返回值的安全性
  • 📦 多种序列化格式 - 支持 JSON 和 Postcard 序列化
  • 📊 遥测支持 - 可选的指标收集和分布式追踪功能

快速开始

Cargo.toml 中添加依赖:

[dependencies]

serverless-fn = "0.1.0"

serde = { version = "1.0", features = ["derive"] }

tokio = { version = "1", features = ["full"] }

使用方法

定义 Serverless 函数

use serverless_fn::{serverless, ServerlessError};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub struct Post {
    pub id: u64,
    pub title: String,
    pub content: String,
}

// 使用 #[serverless] 属性标记需要作为 Serverless 函数暴露的函数
#[serverless]
pub async fn read_posts(how_many: usize, query: String) -> Result<Vec<Post>, ServerlessError> {
    let posts = (0..how_many)
        .map(|i| Post {
            id: i as u64,
            title: format!("Post {}", i),
            content: format!("Content of post {}", i),
        })
        .collect();

    Ok(posts)
}

调用 Serverless 函数

use serverless_fn::{serverless, ServerlessError, config};

#[tokio::main]
async fn main() -> Result<(), ServerlessError> {
    // 初始化配置和日志
    let cfg = config::Config::from_env();
    cfg.init_logging();

    // 调用 serverless 函数就像调用普通函数一样
    let posts = read_posts(3, "my search".to_string()).await?;
    println!("Retrieved {} posts", posts.len());

    Ok(())
}

启动服务器

use serverless_fn::server::{FunctionServer, ServerlessError};

#[tokio::main]
async fn main() -> Result<(), ServerlessError> {
    // 方法 1: 使用构建器模式
    FunctionServer::new()
        .host("0.0.0.0")
        .port(3000)
        .start()
        .await
        .map_err(|e| ServerlessError::RemoteExecution(e.to_string()))?;

    Ok(())
}
use serverless_fn::server::{FunctionServer, ServerConfig, ServerlessError};

#[tokio::main]
async fn main() -> Result<(), ServerlessError> {
    let config = ServerConfig::new()
        .host("0.0.0.0")
        .port(3000);
    
    FunctionServer::with_config(config)
        .start()
        .await
        .map_err(|e| ServerlessError::RemoteExecution(e.to_string()))?;
    
    Ok(())
}

优雅关闭

use serverless_fn::server::{FunctionServer, ServerlessError};
use tokio::signal;

#[tokio::main]
async fn main() -> Result<(), ServerlessError> {
    FunctionServer::new()
        .host("0.0.0.0")
        .port(3000)
        .start_with_graceful_shutdown(async {
            let _ = signal::ctrl_c().await;
        })
        .await
        .map_err(|e| ServerlessError::RemoteExecution(e.to_string()))?;
    
    Ok(())
}

特性标志

Feature 描述 默认
remote_call 启用远程调用模式
local_call 启用本地函数调用模式
json_serialization 使用 JSON 进行序列化
postcard_serialization 使用 Postcard 进行序列化
mock_server 启用模拟服务器用于测试
telemetry 启用遥测和监控功能

配置选项

环境变量

变量名 描述 默认值
SERVERLESS_BASE_URL 远程服务的基础 URL http://localhost:3000
SERVERLESS_TIMEOUT 请求超时时间(毫秒) 30000
SERVERLESS_RETRIES 重试次数 3
SERVERLESS_LOG_LEVEL 日志级别 info

编程方式配置

use serverless_fn::config::{Config, DeployStrategy, ConfigBuilder};
use std::time::Duration;

// 方法 1: 使用 Builder 模式
let config = Config::builder()
    .base_url("http://api.example.com")
    .timeout(Duration::from_secs(60))
    .retries(5)
    .log_level("debug")
    .deploy_strategy(DeployStrategy::Remote)
    .build();

// 方法 2: 从环境变量加载
let config = Config::from_env();

// 初始化日志
config.init_logging();

架构模块

模块 描述
client 客户端运行时,负责发起远程调用
server 服务端运行时,负责处理函数请求
transport 传输层抽象,HTTP 传输实现
serializer 序列化/反序列化模块,支持 JSON 和 Postcard
config 配置管理模块
error 统一错误处理模块
telemetry 遥测和监控模块

错误处理

ServerlessError 定义了统一的错误类型:

pub enum ServerlessError {
    Transport(String),           // 网络传输相关错误
    Serialization(String),       // 序列化/反序列化错误
    RemoteExecution(String),     // 远程函数执行错误
    Timeout(String),             // 请求超时错误
    Authentication(String),      // 认证失败错误
    Generic(String),             // 通用错误
}

错误处理示例

use serverless_fn::ServerlessError;

async fn handle_request() -> Result<(), ServerlessError> {
    let result = read_posts(10, "query".to_string()).await?;
    
    // 处理结果
    Ok(())
}

// 或者使用 match 进行更细粒度的错误处理
match read_posts(10, "query".to_string()).await {
    Ok(posts) => println!("Got {} posts", posts.len()),
    Err(ServerlessError::Transport(e)) => eprintln!("Network error: {}", e),
    Err(ServerlessError::Serialization(e)) => eprintln!("Serialization error: {}", e),
    Err(e) => eprintln!("Other error: {}", e),
}

示例

完整示例

运行示例代码:

# 作为服务器运行

cargo run --example usage_example -- --serve


# 作为客户端运行

cargo run --example usage_example

启用遥测功能

[dependencies]

serverless-fn = { version = "0.1.0", features = ["telemetry"] }

use serverless_fn::telemetry;

#[tokio::main]
async fn main() -> Result<(), ServerlessError> {
    // 初始化遥测
    telemetry::init_telemetry();
    
    // 使用遥测中间件
    let result = telemetry::telemetry_middleware("read_posts", async {
        read_posts(10, "query".to_string()).await
    }).await?;
    
    // 获取指标
    let collector = telemetry::get_metrics_collector();
    println!("Total invocations: {}", collector.invocation_count());
    println!("Average duration: {}ms", collector.avg_duration_ms());
    
    Ok(())
}

开发

构建要求

  • Rust 1.70+

运行测试

# 运行所有测试

cargo test


# 运行特定测试

cargo test --lib


# 运行 clippy 检查

cargo clippy --all-targets -- -D warnings


# 格式化代码

cargo fmt --all

许可证

本项目采用 MIT 许可证。详见 LICENSE 文件。

贡献

欢迎贡献代码、报告问题或提出建议!

  1. Fork 本仓库
  2. 创建你的特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交你的更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启一个 Pull Request

相关链接