# Serverless Function Library
[](https://crates.io/crates/serverless-fn)
[](https://docs.rs/serverless-fn)
[](https://opensource.org/licenses/MIT)
一个用于简化 Serverless 函数开发和调用的 Rust 库。核心设计理念是让调用 Serverless 函数如同调用普通函数一样简单,通过 Feature 标志灵活控制函数的调用方式(远程调用或本地调用)。
## 目录
- [功能特点](#功能特点)
- [快速开始](#快速开始)
- [使用方法](#使用方法)
- [特性标志](#特性标志)
- [配置选项](#配置选项)
- [架构模块](#架构模块)
- [错误处理](#错误处理)
- [示例](#示例)
## 功能特点
- **🎯 简化调用接口** - 提供与普通函数相同的调用语法,隐藏底层网络通信、序列化等复杂性
- **🚀 智能部署策略** - 根据 Feature 标志自动选择部署方式,支持远程调用和本地调用
- **🔧 本地调试友好** - 在本地环境中无需实际部署即可测试
- **🔒 类型安全** - 使用 Rust 的类型系统确保参数和返回值的安全性
- **📦 多种序列化格式** - 支持 JSON 和 Postcard 序列化
- **📊 遥测支持** - 可选的指标收集和分布式追踪功能
## 快速开始
在 `Cargo.toml` 中添加依赖:
```toml
[dependencies]
serverless-fn = "0.1.0"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
```
## 使用方法
### 定义 Serverless 函数
```rust
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 函数
```rust
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(())
}
```
### 启动服务器
```rust
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(())
}
```
```rust
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(())
}
```
#### 优雅关闭
```rust
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(())
}
```
## 特性标志
| `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` |
### 编程方式配置
```rust
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` 定义了统一的错误类型:
```rust
pub enum ServerlessError {
Transport(String), // 网络传输相关错误
Serialization(String), // 序列化/反序列化错误
RemoteExecution(String), // 远程函数执行错误
Timeout(String), // 请求超时错误
Authentication(String), // 认证失败错误
Generic(String), // 通用错误
}
```
### 错误处理示例
```rust
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),
}
```
## 示例
### 完整示例
运行示例代码:
```bash
# 作为服务器运行
cargo run --example usage_example -- --serve
# 作为客户端运行
cargo run --example usage_example
```
### 启用遥测功能
```toml
[dependencies]
serverless-fn = { version = "0.1.0", features = ["telemetry"] }
```
```rust
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+
### 运行测试
```bash
# 运行所有测试
cargo test
# 运行特定测试
cargo test --lib
# 运行 clippy 检查
cargo clippy --all-targets -- -D warnings
# 格式化代码
cargo fmt --all
```
## 许可证
本项目采用 MIT 许可证。详见 [LICENSE](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
## 相关链接
- [文档](https://docs.rs/serverless-fn)
- [Crates.io](https://crates.io/crates/serverless-fn)
- [GitHub 仓库](https://github.com/example/serverless-fn)