Rust Web框架Actix插件paperclip-actix的使用:为RESTful API开发提供OpenAPI支持与自动化文档生成
Rust Web框架Actix插件paperclip-actix的使用:为RESTful API开发提供OpenAPI支持与自动化文档生成
安装
在项目目录中运行以下Cargo命令:
cargo add paperclip-actix
或者在Cargo.toml中添加以下行:
paperclip-actix = "0.7.3"
完整示例demo
以下是一个使用paperclip-actix为Actix-web应用添加OpenAPI支持和自动化文档生成的完整示例:
use actix_web::{web, App, HttpServer, Responder};
use paperclip::actix::{
// 使用Apiv2Schema代替默认的serde::Serialize
api_v2_operation,
// 使用OpenApiExt扩展Actix-web应用
OpenApiExt,
};
// 定义一个简单的结构体作为响应
#[derive(serde::Serialize, paperclip::actix::Apiv2Schema)]
struct HelloResponse {
message: String,
}
// 使用api_v2_operation宏标记API操作
#[api_v2_operation]
async fn hello() -> impl Responder {
web::Json(HelloResponse {
message: "Hello, world!".to_string(),
})
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
// 启用OpenAPI支持
.wrap_api()
// 添加API路由
.service(
web::resource("/hello")
.route(web::get().to(hello))
// 添加API文档元数据
.with_api_spec(|| {
paperclip::v2::models::Operation {
summary: Some("Say hello".to_string()),
description: Some("A simple hello endpoint".to_string()),
..Default::default()
}
}),
)
// 添加Swagger UI
.with_swagger_ui_at("/api/docs")
// 构建Actix-web应用
.build()
})
.bind("127.0.0.1:8080")?
.run()
.await
}
功能说明
- OpenAPI规范支持:通过
wrap_api()
方法启用OpenAPI支持 - 自动文档生成:使用
with_swagger_ui_at()
方法添加Swagger UI界面 - API元数据:使用
with_api_spec()
为路由添加描述信息 - Schema支持:使用
Apiv2Schema
派生宏为数据结构提供OpenAPI schema
运行和访问
- 启动应用程序后,查看Swagger UI界面
- API端点
/hello
将自动出现在文档中 - 可以交互式地测试API端点
注意事项
- 确保所有响应类型都实现了
Apiv2Schema
trait - 使用
api_v2_operation
宏标记所有API处理函数 - 可以通过
with_api_spec()
方法为路由添加更多元数据
1 回复
Rust Web框架Actix插件paperclip-actix使用指南
完整示例代码
下面是一个完整的paperclip-actix使用示例,集成了前面提到的各种功能:
use actix_web::{web, App, HttpResponse, HttpServer, Result};
use paperclip::actix::{
api_v2_operation,
Apiv2Schema,
OpenApiExt
};
use serde::{Serialize, Deserialize};
// 定义宠物数据结构
#[derive(Debug, Serialize, Deserialize, Apiv2Schema)]
struct Pet {
id: u64,
name: String,
tag: Option<String>,
}
// 定义错误响应结构
#[derive(Debug, Serialize, Apiv2Schema)]
struct ErrorResponse {
code: u32,
message: String,
}
/// 获取所有宠物信息
///
/// 这个端点返回系统中所有的宠物信息列表
#[api_v2_operation(
responses(
(status = 200, description = "成功获取宠物列表", body = Vec<Pet>),
(status = 500, description = "服务器内部错误", body = ErrorResponse)
),
tags("pets")
)]
async fn get_pets() -> Result<web::Json<Vec<Pet>>, web::Json<ErrorResponse>> {
Ok(web::Json(vec![
Pet {
id: 1,
name: "Fluffy".into(),
tag: Some("cat".into()),
},
Pet {
id: 2,
name: "Rex".into(),
tag: Some("dog".into()),
}
]))
}
/// 根据ID获取特定宠物信息
#[api_v2_operation(
params(
("id" = u64, Path, description = "宠物ID")
),
responses(
(status = 200, description = "成功获取宠物信息", body = Pet),
(status = 404, description = "宠物不存在", body = ErrorResponse)
),
tags("pets")
)]
async fn get_pet_by_id(pet_id: web::Path<u64>) -> Result<web::Json<Pet>, web::Json<ErrorResponse>> {
if *pet_id == 1 {
Ok(web::Json(Pet {
id: 1,
name: "Fluffy".into(),
tag: Some("cat".into()),
}))
} else {
Err(web::Json(ErrorResponse {
code: 404,
message: "Pet not found".into(),
}))
}
}
/// 添加新宠物
#[api_v2_operation(
security(
("api_key" = [])
),
responses(
(status = 201, description = "成功创建宠物", body = Pet),
(status = 400, description = "无效输入", body = ErrorResponse)
),
tags("pets")
)]
async fn add_pet(new_pet: web::Json<Pet>) -> Result<web::Json<Pet>, web::Json<ErrorResponse>> {
Ok(web::Json(Pet {
id: new_pet.id,
name: new_pet.name.clone(),
tag: new_pet.tag.clone(),
}))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
// 启用Paperclip
.wrap_api()
// 配置OpenAPI规范路径
.with_json_spec_at("/api/spec")
// 配置Swagger UI路径和自定义设置
.with_swagger_ui_at_with_config("/docs", {
let mut conf = paperclip::actix::SwaggerUIConfig::default();
conf.default_models_expand_depth = -1; // 默认折叠所有模型
conf
})
// 注册路由
.service(
web::resource("/pets")
.route(web::get().to(get_pets))
.route(web::post().to(add_pet))
)
.service(
web::resource("/pets/{id}")
.route(web::get().to(get_pet_by_id))
)
.build()
})
.bind("127.0.0.1:8080")?
.run()
.await
}
示例说明
-
数据结构:
- 定义了
Pet
和ErrorResponse
结构体,并实现了Apiv2Schema
trait - 使用
Serialize
和Deserialize
来自动序列化/反序列化
- 定义了
-
API端点:
get_pets
: 获取所有宠物列表get_pet_by_id
: 根据ID获取特定宠物add_pet
: 添加新宠物
-
文档生成:
- 使用
#[api_v2_operation]
宏添加操作文档 - 包含响应状态码描述、参数描述和标签
- 添加了安全定义(api_key)
- 使用
-
Swagger UI配置:
- 自定义UI配置,默认折叠所有模型
- 规范JSON位于
/api/spec
- Swagger UI位于
/docs
-
错误处理:
- 定义了统一的错误响应结构
- 每个端点都明确定义了可能的错误响应
这个完整示例展示了如何使用paperclip-actix创建一个有完整文档支持的RESTful API服务,包含了参数文档、响应模型、错误处理和Swagger UI集成等功能。