pub struct ApiRequest {
pub api_path: String,
pub body: Vec<u8>,
pub query_params: HashMap<String, String>,
pub path_params: HashMap<String, Vec<String>>,
pub file: Vec<u8>,
/* private fields */
}Expand description
API请求的核心数据结构 - 命令模式的体现
ApiRequest 是整个SDK架构的核心,采用命令模式(Command Pattern)设计。
它封装了发起一次飞书API调用所需的所有信息,充当服务层(Service)与传输层(Transport)之间的桥梁。
§设计理念
- 解耦性:服务层只负责构建请求,不关心HTTP细节
- 统一性:所有API调用都通过这个统一的结构体表示
- 灵活性:支持普通请求和multipart/form-data请求
§使用流程
- 服务层方法创建并配置
ApiRequest实例 - 设置HTTP方法、路径、认证需求等基本信息
- 根据请求类型填充
body和/或file字段 - 将配置好的请求传递给
Transport::request进行处理
§示例
ⓘ
// 普通JSON请求
let mut api_req = ApiRequest {
http_method: Method::POST,
api_path: "/open-apis/drive/v1/files".to_string(),
body: serde_json::to_vec(&request_data).unwrap(),
..Default::default()
};
// 文件上传请求(multipart)
let mut api_req = ApiRequest {
http_method: Method::POST,
api_path: "/open-apis/drive/v1/files/upload".to_string(),
body: serde_json::to_vec(&metadata).unwrap(), // JSON元数据
file: file_bytes, // 文件内容
..Default::default()
};Fields§
§api_path: StringAPI的相对路径
例如:/open-apis/drive/v1/files/{file_id}
路径中的动态参数(如 {file_id})通常通过 format! 宏直接嵌入,
而不是使用 path_params 字段。
body: Vec<u8>请求体数据(序列化后的字节数组)
§在不同请求类型中的用途:
- 普通请求:包含完整的请求体,通常是JSON序列化后的数据
- 文件上传(multipart):仅包含JSON元数据部分,文件内容存储在
file字段 - 无请求体的请求:保持为空
Vec
§注意事项
服务层通常使用 serde_json::to_vec() 将请求结构体序列化到这个字段。
query_params: HashMap<String, String>URL查询参数
存储将被附加到URL末尾的查询参数。
例如:?page_size=10&page_token=xxx
§示例
ⓘ
api_req.query_params.insert("page_size".to_string(), "10".to_string());
api_req.query_params.insert("page_token".to_string(), token);path_params: HashMap<String, Vec<String>>URL路径参数(当前未使用)
原设计意图可能是用于路径模板替换,如将 /files/{id} 中的 {id} 替换。
但当前实现中,路径参数都是通过 format! 宏直接嵌入到 api_path 中。
§TODO
考虑移除此字段或实现路径模板功能以保持设计一致性。
file: Vec<u8>文件内容(用于multipart/form-data请求)
§在不同请求类型中的用途:
- 普通请求:保持为空
Vec - 文件上传(multipart):包含要上传的文件的二进制内容
§工作原理
当 file 字段非空时,Transport层会自动识别这是一个multipart请求:
body字段的内容作为multipart的JSON元数据部分file字段的内容作为文件部分- Content-Type自动设置为
multipart/form-data
§示例
ⓘ
// 文件上传请求
api_req.body = serde_json::to_vec(&FileMetadata {
name: "document.pdf",
parent_id: "folder123",
}).unwrap();
api_req.file = std::fs::read("path/to/document.pdf").unwrap();Trait Implementations§
Source§impl Clone for ApiRequest
impl Clone for ApiRequest
Source§fn clone(&self) -> ApiRequest
fn clone(&self) -> ApiRequest
Returns a duplicate of the value. Read more
1.0.0 · Source§const fn clone_from(&mut self, source: &Self)
const fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for ApiRequest
impl Debug for ApiRequest
Source§impl Default for ApiRequest
impl Default for ApiRequest
Source§fn default() -> ApiRequest
fn default() -> ApiRequest
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for ApiRequest
impl RefUnwindSafe for ApiRequest
impl Send for ApiRequest
impl Sync for ApiRequest
impl Unpin for ApiRequest
impl UnwindSafe for ApiRequest
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more