wae-schema 0.0.2

WAE Schema - 数据结构定义与验证
Documentation

wae-schema

Schema 模块 - 提供数据结构定义、验证和 OpenAPI 文档生成。

主要功能

  • Schema 定义: 类型安全的数据结构
  • Schema 构建器: 流畅的 API 构建 JSON Schema
  • OpenAPI 文档生成: 自动生成 OpenAPI 3.1 规范的 API 文档
  • Swagger UI 集成: 内置 Swagger UI 界面,方便 API 测试和文档查看
  • axum 集成: 与 axum 框架无缝集成,提供文档服务端点
  • ToSchema trait: 为 Rust 标准类型提供自动 Schema 生成

技术栈

  • 序列化: serde, serde_json
  • OpenAPI 规范: OpenAPI 3.1
  • Web 框架: axum (可选功能)
  • Swagger UI: 从 CDN 加载的 Swagger UI 5.x

功能特性

Schema 构建

使用流畅的 API 构建 JSON Schema:

use wae_schema::Schema;

let user_schema = Schema::object()
    .title("User")
    .description("用户信息")
    .property("id", Schema::integer().description("用户 ID"))
    .property("username", Schema::string().min_length(1).max_length(50))
    .property("email", Schema::string().format("email"))
    .property("age", Schema::integer().minimum(0).maximum(150))
    .required(vec!["id", "username", "email"]);

使用 SchemaBuilder

use wae_schema::SchemaBuilder;

let product_schema = SchemaBuilder::object()
    .title("Product")
    .property("name", Schema::string())
    .property("price", Schema::number())
    .build();

OpenAPI 文档构建

使用 OpenApiBuilder 构建完整的 API 文档:

use wae_schema::{
    OpenApiBuilder, PathItem, Operation, Response, Schema,
    RequestBody, Parameter, ParameterLocation
};

let doc = OpenApiBuilder::with_title_and_version("用户 API", "1.0.0")
    .description("用户管理相关的 API 接口")
    .tag("用户", Some("用户管理操作"))
    .path(
        "/users/{id}",
        PathItem::new()
            .get(
                Operation::new()
                    .summary("获取用户信息")
                    .description("根据用户 ID 获取用户详细信息")
                    .operation_id("get_user")
                    .tag("用户")
                    .parameter(Parameter::path("id")
                        .description("用户 ID")
                        .schema(Schema::integer()))
                    .response("200", Response::new("成功").json(Schema::object()))
            )
    )
    .build();

与 axum 集成

将 OpenAPI 文档作为服务端点提供:

use axum::Router;
use wae_schema::{OpenApiDoc, OpenApiBuilder};
use wae_schema::openapi::axum::openapi_router;

#[tokio::main]
async fn main() {
    let doc = OpenApiBuilder::with_title_and_version("我的 API", "1.0.0").build();
    
    let app = Router::new()
        .merge(openapi_router(doc));
    
    axum::Server::bind(&"127.0.0.1:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

访问 /openapi.json 获取 JSON 格式的 OpenAPI 文档。

使用自定义配置

use wae_schema::openapi::axum::{OpenApiService, OpenApiServiceConfig};

let config = OpenApiServiceConfig::new()
    .json_path("/api-docs.json")
    .yaml_path("/api-docs.yaml")
    .enable_json(true)
    .enable_yaml(false);

let service = OpenApiService::with_config(doc, config);
let router = service.into_router();

合并到现有路由

use axum::Router;
use wae_schema::openapi::axum::merge_openapi_router;

let mut app = Router::new();
app = merge_openapi_router(app, doc);

Swagger UI 集成

添加 Swagger UI 界面:

use axum::Router;
use wae_schema::swagger_ui::SwaggerUiService;
use wae_schema::swagger_ui::SwaggerUiConfig;

let swagger_config = SwaggerUiConfig::new()
    .openapi_url("/openapi.json")
    .title("我的 API 文档");

let swagger_service = SwaggerUiService::new(swagger_config);
let swagger_router = swagger_service.router();

let app = Router::new()
    .merge(openapi_router(doc))
    .merge(swagger_router);

访问 /swagger-ui 查看交互式 API 文档界面。

完整示例

结合 OpenAPI 文档和 Swagger UI 的完整示例:

use axum::Router;
use wae_schema::{
    OpenApiBuilder, OpenApiDoc, PathItem, Operation, Response, Schema,
    openapi::axum::openapi_router,
    swagger_ui::{SwaggerUiService, SwaggerUiConfig}
};

fn create_openapi_doc() -> OpenApiDoc {
    OpenApiBuilder::with_title_and_version("电商 API", "2.0.0")
        .description("电商平台的 RESTful API 文档")
        .server("http://localhost:3000", Some("本地开发服务器"))
        .tag("商品", Some("商品管理接口"))
        .tag("订单", Some("订单管理接口"))
        .path(
            "/products",
            PathItem::new()
                .get(
                    Operation::new()
                        .summary("获取商品列表")
                        .tag("商品")
                        .response("200", Response::new("成功").json(Schema::array(Schema::object())))
                )
                .post(
                    Operation::new()
                        .summary("创建商品")
                        .tag("商品")
                        .response("201", Response::new("创建成功").json(Schema::object()))
                )
        )
        .path(
            "/products/{id}",
            PathItem::new()
                .get(
                    Operation::new()
                        .summary("获取商品详情")
                        .tag("商品")
                        .parameter(Parameter::path("id").schema(Schema::integer()))
                        .response("200", Response::new("成功").json(Schema::object()))
                )
        )
        .build()
}

#[tokio::main]
async fn main() {
    let doc = create_openapi_doc();
    
    let swagger_config = SwaggerUiConfig::new()
        .title("电商 API 文档");
    
    let app = Router::new()
        .merge(openapi_router(doc))
        .merge(SwaggerUiService::new(swagger_config).router());
    
    println!("服务器运行在 http://127.0.0.1:3000");
    println!("OpenAPI JSON: http://127.0.0.1:3000/openapi.json");
    println!("Swagger UI: http://127.0.0.1:3000/swagger-ui");
    
    axum::Server::bind(&"127.0.0.1:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

特性标志

  • axum: 启用 axum 框架集成
  • yaml: 启用 YAML 格式的 OpenAPI 文档输出

在 Cargo.toml 中启用:

[dependencies]
wae-schema = { version = "0.0.0", features = ["axum", "yaml"] }

ToSchema trait

为常见 Rust 类型提供自动 Schema 生成:

use wae_schema::ToSchema;

let string_schema = String::schema();
let int_schema = i32::schema();
let vec_schema = Vec::<String>::schema();
let option_schema = Option::<i64>::schema();

支持的类型:

  • 字符串: String
  • 整数: i8, i16, i32, i64, u8, u16, u32, u64
  • 浮点数: f32, f64
  • 布尔: bool
  • 数组: Vec<T> where T: ToSchema
  • 可选: Option<T> where T: ToSchema
  • JSON 值: serde_json::Value