#path #utoipa #openapi #swagger #auto

utoipauto-macro

Rust宏,用于在编译阶段自动添加Paths/Schemas到Utoipa crate,模拟反射

18次发布

新增 0.1.14 2024年8月5日
0.1.12 2024年7月2日
0.1.11 2024年6月5日
0.1.10 2024年3月7日
0.0.4 2023年12月1日

2012过程宏 中排名

Download history 569/week @ 2024-04-15 521/week @ 2024-04-22 582/week @ 2024-04-29 557/week @ 2024-05-06 816/week @ 2024-05-13 874/week @ 2024-05-20 678/week @ 2024-05-27 1457/week @ 2024-06-03 1774/week @ 2024-06-10 1748/week @ 2024-06-17 2284/week @ 2024-06-24 2384/week @ 2024-07-01 1930/week @ 2024-07-08 1362/week @ 2024-07-15 1816/week @ 2024-07-22 1797/week @ 2024-07-29

每月下载量:7,144
用于 utoipauto

MIT/Apache

67KB
1.5K SLoC

Utoipauto

Rust宏,用于在编译阶段自动添加Paths/Schemas到Utoipa crate,模拟反射

crate简介

Utoipa是一个用于通过源代码生成文档(openapi/swagger)的优秀crate。

但Rust是一种静态编程语言,我们无法在运行时自动发现路径和DTO并添加到文档中,

对于只有几个端点的API,逐个添加控制器函数和DTO并不麻烦。

但是,如果您有数百甚至数千个端点,代码就会变得非常冗长且难以维护。

示例


#[derive(OpenApi)]
#[openapi(
    paths(
        // <================================ All functions  1 to N
        test_controller::service::func_get_1,
        test_controller::service::func_get_2,
        test_controller::service::func_get_3,
        test_controller::service::func_get_4,
       ....
       ....
       ....
        test_controller::service::func_get_N,

    ),
    components(
        // <====================== All DTO one by one
        schemas(TestDTO_1,  TestDTO_2, ........ , TestDTO_N)
    ),
    tags(
        (name = "todo", description = "Todo management endpoints.")
    ),
    modifiers(&SecurityAddon)
)]
pub struct ApiDoc;

这个crate的目标是提出一个宏,它可以自动检测携带Utoipa宏的方法(#[utoipa::path(...]),并自动添加它们。(它也检测子模块。)

它还会检测为ToSchema派生或实现的结构体,用于components(schemas)部分,以及用于components(responses)部分的结构体。

功能

  • 自动递归路径检测
  • 自动从模块导入
  • 自动从src文件夹导入
  • 自动模型检测
  • 自动响应检测
  • 与工作空间兼容
  • 排除方法自动扫描
  • 自定义路径检测

如何使用

只需将crate utoipauto 添加到项目中

cargo add utoipauto

导入宏

use utoipauto::utoipauto;

然后在 #[derive(OpenApi)] 和 #[openapi] 宏之前添加 #[utoipauto] 宏。

重要!!

请将 #[utoipauto] 放在 #[derive(OpenApi)]#[openapi] 宏之前。

#[utoipauto(paths = "MODULE_SRC_FILE_PATH, MODULE_SRC_FILE_PATH, ...")]

路径接收一个必须遵循此结构的字符串

"MODULE_SRC_FILE_PATH, MODULE_SRC_FILE_PATH, ..."

您可以通过逗号分隔来添加多个路径 ","

对泛型模式的支持

我们支持泛型模式,但有一些缺点。
如果您想使用泛型,您有三种方法可以实现。

  1. 使用完整路径
#[aliases(GenericSchema = path::to::Generic<path::to::Schema>)]
  1. 导入 utoipauto 所在的位置
use path::to::schema;
  1. 使用 generic_full_path 功能

请注意,此功能会导致构建时间开销更大。
更高的 RAM 使用量,更长的编译时间和过度的磁盘使用(特别是在大型项目中)是后果。

utoipauto = { version = "*", feature = ["generic_full_path"] }

与工作空间一起使用

如果您正在使用工作空间,您必须指定路径中 crate 的名称。
即使您在同一个 crate 中使用 #[utoipauto],这也适用。

#[utoipauto(paths = "./utoipauto/src")]

您可以通过使用 from 键来指定指定的路径来自另一个 crate。

#[utoipauto(paths = "./utoipauto/src from utoipauto")]

从 src 文件夹导入

如果没有指定路径,宏将自动扫描 src 文件夹,并添加所有携带 #[utoipa::path(...)] 宏的方法,以及所有推导自 ToSchemaToResponse 的结构体。以下是如何添加 src 代码中所有方法的示例。

...

use utoipauto::utoipauto;

...
#[utoipauto]
#[derive(OpenApi)]
#[openapi(
    tags(
        (name = "todo", description = "Todo management endpoints.")
    ),
    modifiers(&SecurityAddon)
)]

pub struct ApiDoc;

...

从模块导入

以下是添加其余模块中所有方法和结构的示例。


use utoipauto::utoipauto;

#[utoipauto(
  paths = "./src/rest"
  )]
#[derive(OpenApi)]
#[openapi(
    tags(
        (name = "todo", description = "Todo management endpoints.")
    ),
    modifiers(&SecurityAddon)
)]

pub struct ApiDoc;

以下是添加位于子文件夹中的其余模块中所有方法和结构的示例


use utoipauto::utoipauto;

#[utoipauto(
  paths = "(./src/lib/rest from crate::rest)"
  )]
#[derive(OpenApi)]
#[openapi(
    tags(
        (name = "todo", description = "Todo management endpoints.")
    ),
    modifiers(&SecurityAddon)
)]

pub struct ApiDoc;

从文件名导入

以下是添加 test_controller 和 test2_controller 模块中所有方法的示例。您也可以将自动添加和手动添加相结合,如在这里,我们手动将方法添加到文档 "other_controller::get_users" 和模式 "TestDTO" 中。


use utoipauto::utoipauto;

#[utoipauto(
  paths = "./src/rest/test_controller.rs,./src/rest/test2_controller.rs "
  )]
#[derive(OpenApi)]
#[openapi(
    paths(

        crate::rest::other_controller::get_users,
    ),
    components(
        schemas(TestDTO)
    ),
    tags(
        (name = "todo", description = "Todo management endpoints.")
    ),
    modifiers(&SecurityAddon)
)]

pub struct ApiDoc;



排除方法自动扫描

您可以通过添加以下宏 #[utoipa_ignore] 从 Doc Path 列表排除一个函数。

示例

    /// Get all pets from database
    ///
    #[utoipa_ignore]  //<============== this Macro
    #[utoipa::path(
        responses(
            (status = 200, description = "List all Pets", body = [ListPetsDTO])
        )
    )]
    #[get("/pets")]
    async fn get_all_pets(req: HttpRequest, store: web::Data<AppState>) -> impl Responder {
        // your CODE
    }

从自动扫描中排除一个结构体

您也可以通过添加以下宏 #[utoipa_ignore] 从模型和响应列表中排除一个结构体。

示例

    #[utoipa_ignore]  //<============== this Macro
    #[derive(ToSchema)]
    struct ModelToIgnore {
        // your CODE
    }

自定义路径检测

默认情况下,此宏将查找具有 #[utoipa::path(...)] 属性的函数,但您也可以指定要查找的自定义属性。

#[handler]
pub fn custom_router() {
    // ...
}

#[utoipauto(function_attribute_name = "handler")] //Custom attribute
#[derive(OpenApi)]
#[openapi(tags()))]
pub struct ApiDoc;

您还可以为模型和响应检测指定自定义属性。

#[derive(Schema, Response)]
pub struct CustomModel {
    // ...
}

#[utoipauto(schema_attribute_name = "Schema", response_attribute_name = "Response")] //Custom derive
#[derive(OpenApi)]
#[openapi(tags())]
pub struct ApiDoc;

注意

包含带有 utoipa::path 标签的方法的子模块也会自动检测。

贡献

欢迎贡献,请随意提交 PR 或问题。

灵感

灵感来源于 utoipa_auto_discovery



依赖项

~280–730KB
~17K SLoC