46 个版本 (稳定版)
新 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.2.3 | 2024 年 5 月 7 日 |
0.1.0-beta6 | 2022 年 3 月 7 日 |
#19 在 网页编程 中
312,232 每月下载量
用于 473 个包 (433 个直接使用)
380KB
6K SLoC
utoipa - 自动生成的 OpenAPI 文档
发音为 /u:ˈtoʊ:i.pɑ/ 或 /u:ˈtoʊˌaɪ.piˈeɪ/,哪种对你来说更方便。
想用 OpenAPI 记录您的 API,但又不想手动调整 YAML 或 JSON?希望它足够简单,几乎达到理想状态?不用担心:utoipa 就是为了填补这个空缺而生的。它的目标是,如果不是全部,至少完成大部分繁重的工作,让您能专注于编写实际的 API 逻辑而不是文档。它旨在做到 最小化、简单 和 快速。它使用简单的 proc
宏,您可以使用它来注释您的代码以便文档化。
utoipa
包为 Rust REST API 提供自动生成的 OpenAPI 文档。它将代码优先方法视为一等公民,并通过提供简单的宏来简化 API 文档的生成。
它还包含 OpenAPI 规范的 Rust 类型,允许您仅使用 Rust 编写 OpenAPI 规范,如果自动生成不是您的首选或不符合您的目的。
该库的长期目标是成为在 Rust 代码库中需要 OpenAPI 文档时的首选之地。
Utoipa 是框架无关的,可以与任何网页框架一起使用,甚至在没有框架的情况下使用。虽然它是可移植的和独立的,但其关键特性之一是与网页框架的简单集成。
选择您喜欢的口味,并用冰冷的 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 框架集成,允许用户使用IntoParams
而无需定义parameter_in
属性。有关详细信息,请参阅 文档 或 示例。debug
:向 openapi 定义和其他地方添加额外的特质,如 debug 特质。chrono
:添加对 chronoDateTime
、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(paths(...))]
宏属性的顺序。如果禁用,则路径将按字母顺序排序。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"] }
**注意**!要使用 utoipa
与 Swagger UI 一起使用,可以使用 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();
请参阅Modify特质以获取如何通过它修改生成的OpenAPI的示例。
深入了解
- 查看如何通过Swagger UI提供服务端OpenAPI文档,请查阅utoipa-swagger-ui存储库以获取更多详细信息。
- 浏览示例以获取更全面的示例。
- 请查看IntoResponses和ToResponse以了解如何派生响应。
- 有关OpenAPI安全性的更多信息,请参阅安全文档。
- 在构建时将生成的API文档输出到文件。请参阅问题214评论。
常见问题解答(FAQ)
Swagger UI从构建的二进制文件返回404NotFound
这很可能是因为RustEmbed
没有将Swagger UI嵌入到可执行文件中。这是自然的,因为RustEmbed
库在默认情况下不会在调试构建中嵌入文件。为了解决这个问题,您可以执行以下操作之一。
- 以
--release
模式构建您的可执行文件 - 或向您的
Cargo.toml
中的utoipa-swagger-ui
添加debug-embed
功能标志。这将启用debug-emebed
功能标志,同时为RustEmbed
。有关更多信息,请参阅此处和此处。
如何为外部类型实现ToSchema
?
有几种方法可以解决这个问题,具体请参阅此处的详细说明。
如何使用Rust的类型别名?
目前这是不可能的,因为没有方法可以评估proc宏代码生成中可见的类型令牌背后的实际类型。如果可以实现全局别名注册,这可能在将来成为可能。有关此问题的相关问题,请参阅#766。
如何自动发现OpenAPI模式和路径?
目前没有内置的解决方案来自动发现OpenAPI类型,但幸运的是,有一个非常棒的存储库可以为您完成这项工作,名为utoipauto。
许可证
根据您的选择,在Apache 2.0或MIT许可证下授权。
除非您明确说明,否则您提交给包括在此存储库中的任何贡献,都应双重授权,没有任何额外的条款或条件。
依赖关系
~1.5–3.5MB
~73K SLoC