45个版本 (稳定)
新 5.0.0-alpha.2 | 2024年8月23日 |
---|---|
5.0.0-alpha.1 | 2024年7月27日 |
5.0.0-alpha.0 | 2024年5月30日 |
4.3.0 | 2024年5月5日 |
0.1.0-beta6 | 2022年3月7日 |
1799 在 过程宏 中
312,183 每月下载次数
在 474 个crate中使用 (直接使用3个)
590KB
12K SLoC
utoipa - 自动生成的OpenAPI文档
发音 /u:ˈtoʊ:i.pɑ/ 或 /u:ˈtoʊˌaɪ.piˈeɪ/ 取决于哪个对你来说更合适。
想要使用OpenAPI文档化你的API,但又不想手动调整YAML或JSON?希望它变得如此简单,以至于几乎像是乌托邦式的?别担心:utoipa就是为了填补这个空缺而存在的。它旨在为你做尽可能多的繁重工作,让你能专注于编写实际的API逻辑,而不是文档。它旨在做到 最小化、简单 和 快速。它使用简单的 proc
宏,你可以使用这些宏来注解你的代码,以便进行文档化。
utoipa
crate为Rust REST API提供自动生成的OpenAPI文档。它将代码优先方法视为一等公民,并通过提供用于从代码生成文档的简单宏来简化API文档。
它还包含OpenAPI规范的Rust类型,允许你仅在自动生成不是你的口味或不适合你的目的时,仅使用Rust编写OpenAPI规范。
该库的长期目标是成为在任何Rust代码库中需要OpenAPI文档时的首选之地。
Utoipa是框架无关的,可以与任何Web框架一起使用,甚至可以不使用任何框架。虽然它是可移植的和独立的,但其关键特性之一是简单集成到Web框架中。
选择你的风味,并用冰冷的IPA来文档化你的API
参考以下框架中构建“todo”应用的现有 示例
所有示例均包含 Swagger-UI,除非另有说明。
还有在单个应用程序中构建多个 OpenAPI 文档的示例,每个文档在 Swagger UI 中独立。这些示例仅适用于 actix 和 warp 框架。
即使没有您喜欢的框架的示例,utoipa
也可以与任何支持用宏装饰函数的 Web 框架一起使用,类似于 warp 和 tide 的示例。
社区示例
这个词语游戏是什么意思?
这个名字来源于单词 utopic
和 api
,其中 uto
是 utopic 的前三个字母,而 ipa
是 api 的反写。还有... ipa
也是一种很棒的啤酒类型 🍺。
组件功能
yaml
:启用 OpenAPI 对象的 serde_yaml 序列化。actix_extras
:增强 actix-web 集成,能够解析来自 actix web 路径属性宏的path
、query
参数。有关详细信息,请参阅 文档 或 示例。rocket_extras
:增强 rocket 框架集成,能够解析来自 rocket 路径属性宏的path
、query
参数。有关详细信息,请参阅 文档 或 示例。axum_extras
:增强 axum 框架集成,允许用户在不定义parameter_in
属性的情况下使用IntoParams
。有关详细信息,请参阅 文档 或 示例。debug
:向 OpenAPI 定义和其他地方添加额外的特质,如 debug 特质。chrono
:支持 chrono 的DateTime
、Date
、NaiveDate
、NaiveDateTime
、NaiveTime
和Duration
类型。默认情况下,这些类型被解析为带有额外format
信息的string
类型。对于DateTime
和NaiveDateTime
使用format: date-time
,对于Date
和NaiveDate
使用format: date
,根据 RFC3339 作为ISO-8601
。要覆盖默认的string
表示形式,用户必须使用value_type
属性来覆盖类型。有关详细信息,请参阅 文档。time
:增加对 timeOffsetDateTime
、PrimitiveDateTime
、Date
和Duration
类型的支持。默认情况下,这些类型将被解析为string
。OffsetDateTime
和PrimitiveDateTime
将使用date-time
格式。Date
将使用date
格式,而Duration
将不使用任何格式。要覆盖默认的string
表示,用户必须使用value_type
属性来覆盖类型。有关详细信息,请参阅 文档。decimal
:增加对 rust_decimalDecimal
类型的支持。默认情况下,它被解释为String
。如果您想更改格式,您需要覆盖类型。请参阅 组件派生文档 中的value_type
。decimal_float
:增加对 rust_decimalDecimal
类型的支持。默认情况下,它被解释为Number
。此功能与 decimal 功能互斥,并允许更改文档中用于Decimal
的默认类型,就像 rust_decimal 提供的serde_with_float
功能一样。uuid
:增加对 uuid 的支持。在 OpenAPI 规范中,Uuid
类型将以格式uuid
的String
表示。ulid
:增加对 ulid 的支持。在 OpenAPI 规范中,Ulid
类型将以格式ulid
的String
表示。url
:增加对 url 的支持。在 OpenAPI 规范中,Url
类型将以格式uri
的String
表示。smallvec
:增加对 smallvec 的支持。SmallVec
将被视为Vec
。openapi_extensions
:添加了提供额外便利函数的特性和函数。请参阅request_body
文档 中的示例。repr
:为单元枚举类型添加对 repr_serde 的repr(u*)
和repr(i*)
属性的支持,以实现类似 C 枚举的表示。请参阅 文档 获取更多详细信息。preserve_order
:在序列化组件的方案时保留属性顺序。当启用时,属性将按相应结构定义中的字段顺序列出。当禁用时,属性将按字母顺序列出。preserve_path_order
:根据OpenAPI路径被引入的顺序,按照顺序保留OpenAPI路径的顺序。如果禁用,路径将按字母顺序排序。indexmap
:添加对indexmap的支持。启用时,IndexMap
将渲染为类似于BTreeMap
和HashMap
的映射。non_strict_integers
:添加对非标准整数格式int8
、int16
、uint8
、uint16
、uint32
和uint64
的支持。rc_schema
:为Arc<T>
和Rc<T>
类型添加ToSchema
支持。注意!必须单独启用serderc
功能标志,以便允许Arc<T>
和Rc<T>
类型的序列化和反序列化。有关更多信息,请参阅serde功能标志。
Utoipa隐式支持部分serde
属性。有关更多信息,请参阅文档。
安装
将最小依赖声明添加到Cargo.toml
。
[dependencies]
utoipa = "4"
要启用更多功能,例如使用actix框架扩展,可以将依赖项定义为以下内容。
[dependencies]
utoipa = { version = "4", features = ["actix_extras"] }
注意!要与Swagger UI一起使用utoipa
,可以使用utoipa-swagger-ui crate。
示例
创建一个结构体,或者它也可以是一个枚举。向它添加ToSchema
derive宏,以便它可以注册为OpenAPI模式。
use utoipa::ToSchema;
#[derive(ToSchema)]
struct Pet {
id: u64,
name: String,
age: Option<i32>,
}
创建一个处理程序,用于处理您的业务逻辑,并在其上添加path
proc属性宏。
mod pet_api {
/// Get pet by id
///
/// Get pet from database by pet id
#[utoipa::path(
get,
path = "/pets/{id}",
responses(
(status = 200, description = "Pet found successfully", body = Pet),
(status = NOT_FOUND, description = "Pet was not found")
),
params(
("id" = u64, Path, description = "Pet database id to get Pet for"),
)
)]
async fn get_pet_by_id(pet_id: u64) -> Pet {
Pet {
id: pet_id,
age: None,
name: "lightning".to_string(),
}
}
}
Utoipa支持响应中的http StatusCode
。
该属性宏将创建另一个名为__path_
前缀+处理程序函数名的结构体。因此,当您在不同的文件中实现some_handler
函数并想要导出它时,请确保模块中的__path_some_handler
也可以从根访问。
使用以下OpenApi
derive proc宏将上述Schema
和端点与OpenAPI模式相关联。
use utoipa::OpenApi;
#[derive(OpenApi)]
#[openapi(paths(pet_api::get_pet_by_id), components(schemas(Pet)))]
struct ApiDoc;
println!("{}", ApiDoc::openapi().to_pretty_json().unwrap());
这将生成类似以下内容的API文档
{
"openapi": "3.1.0",
"info": {
"title": "application name from Cargo.toml",
"description": "description from Cargo.toml",
"contact": {
"name": "author name from Cargo.toml",
"email": "author email from Cargo.toml"
},
"license": {
"name": "license from Cargo.toml"
},
"version": "version from Cargo.toml"
},
"paths": {
"/pets/{id}": {
"get": {
"tags": [
"pet_api"
],
"summary": "Get pet by id",
"description": "Get pet from database by pet id",
"operationId": "get_pet_by_id",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Pet database id to get Pet for",
"required": true,
"schema": {
"type": "integer",
"format": "int64",
"minimum": 0
}
}
],
"responses": {
"200": {
"description": "Pet found successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
}
}
}
},
"404": {
"description": "Pet was not found"
}
}
}
}
},
"components": {
"schemas": {
"Pet": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"age": {
"type": [
"integer",
"null"
],
"format": "int32"
},
"id": {
"type": "integer",
"format": "int64",
"minimum": 0
},
"name": {
"type": "string"
}
}
}
}
}
}
在运行时修改OpenAPI
您可以通过直接使用生成的类型或使用Modify trait来在运行时修改生成的OpenAPI。
直接通过类型修改生成的OpenAPI。
#[derive(OpenApi)]
#[openapi(
info(description = "My Api description"),
)]
struct ApiDoc;
let mut doc = ApiDoc::openapi();
doc.info.title = String::from("My Api");
您甚至可以将生成的OpenApi
转换为OpenApiBuilder
。
let builder: OpenApiBuilder = ApiDoc::openapi().into();
有关如何通过它修改生成的OpenAPI的示例,请参阅Modify trait。
超越表面
- 有关如何通过Swagger UI提供OpenAPI文档的详细信息,请参阅utoipa-swagger-ui crate。
- 浏览示例以获取更全面的示例。
- 检查 IntoResponses 和 ToResponse 以获取派生响应的示例。
- 有关 OpenAPI 安全性的更多信息,请参阅 安全文档。
- 在构建时将生成的 API 文档输出到文件。请参阅 问题 214 评论。
常见问题解答
Swagger UI 从构建的二进制文件返回 404 NotFound
这很可能是由于 RustEmbed
没有将 Swagger UI 嵌入可执行文件造成的。这是自然的,因为 RustEmbed
库在默认情况下不会在调试构建中嵌入文件。为了解决这个问题,您可以执行以下操作之一。
- 以
--release
模式构建您的可执行文件 - 或将
debug-embed
特性标志添加到您的Cargo.toml
中的utoipa-swagger-ui
。这将启用debug-emebed
特性标志,对于RustEmbed
也是如此。有关更多信息,请参阅 此处 和 此处。
在此处找到 utoipa-swagger-ui
的 特性标志。
如何为外部类型实现 ToSchema
?
有几种方法可以解决这个问题,具体细节请参见 此处。
如何使用 Rust 的类型别名?
目前这是不可能的,因为没有方法来评估 proc macro 代码生成过程中可见的类型标记背后的实际类型。如果可以实施全局别名注册表,这可能在将来实现。有关此问题的相关 issue 请参阅 #766。
自动发现 OpenAPI 架构和路径?
目前没有内置的解决方案来自动发现 OpenAPI 类型,但幸运的是,有一个非常不错的 crate 可以为您完成这项工作,名为 utoipauto。
许可证
根据您的选择,受 Apache 2.0 或 MIT 许可证的约束。
除非您明确声明,否则您提交给包含在此 crate 中的任何贡献都将双许可,没有任何额外的条款或条件。
依赖项
~0.3–1.8MB
~39K SLoC