3 个不稳定版本
0.9.1 | 2023 年 1 月 18 日 |
---|---|
0.9.0 | 2023 年 1 月 18 日 |
0.8.0-rc.1 | 2023 年 1 月 18 日 |
#66 在 #swagger
385 每月下载
在 8 个 crate 中使用 (通过 revolt_rocket_okapi)
43KB
681 行
Okapi
为 Rust/Rocket 项目自动生成 OpenAPI (又称 Swagger) 文档。
不再有过时的文档。Okapi 在设置服务器时会为您生成文档。它结合了 Rust Doc 注释 和编程逻辑来记录您的 API。
生成的 OpenAPI 文件可以由各种程序用来可视化文档。Rocket-okapi 目前包括 RapiDoc 和 Swagger UI,但也支持其他工具。
支持的 OpenAPI 规范:3.0.0
支持的 Rocket 版本 (针对 rocket_okapi
): 0.5.0-rc.1
使用 Okapi 生成的文档示例
- DF Storyteller: RapiDoc,Swagger UI
- ...[^1]
[^1]: 将添加更多示例,如果您有好的示例,请提出问题。
基本用法
use rocket::{get, post, serde::json::Json};
use revolt_rocket_okapi::{openapi, openapi_get_routes, swagger_ui::*};
use serde::{Deserialize, Serialize};
use schemars::JsonSchema;
// Derive JsonSchema for and request/response models
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
struct User {
user_id: u64,
username: String,
#[serde(default)]
email: Option<String>,
}
// Add #[openapi] attribute to your routes
#[openapi]
#[get("/user/<id>")]
fn get_user(id: u64) -> Option<Json<User>> {
Some(Json(User {
user_id: id,
username: "bob".to_owned(),
email: None,
}))
}
// You can tag your routes to group them together
#[openapi(tag = "Users")]
#[post("/user", data = "<user>")]
fn create_user(user: Json<User>) -> Json<User> {
user
}
// You can skip routes that you don't want to include in the openapi doc
#[openapi(skip)]
#[get("/hidden")]
fn hidden() -> Json<&'static str> {
Json("Hidden from swagger!")
}
pub fn make_rocket() -> rocket::Rocket {
rocket::build()
// openapi_get_routes![...] will host the openapi document at `openapi.json`
.mount(
"/",
openapi_get_routes![get_user, create_user, hidden],
)
// You can optionally host swagger-ui too
.mount(
"/swagger-ui/",
make_swagger_ui(&SwaggerUIConfig {
url: "../openapi.json".to_owned(),
..Default::default()
}),
)
}
更多示例
- Json 网页 API:展示 Okapi 基本功能的简单示例。
- UUID:展示基本功能,但使用 UUID 代替普通的
u32/
u64
id。 - 自定义模式:展示如何向 OpenAPI 文件添加更多/自定义信息,并将多个模块合并成一个 OpenAPI 文件。
- 安全请求守卫:展示如何在 OpenAPI 文件中实现身份验证方法。包括:无身份验证、API 密钥、HTTP 身份验证、OAuth2、OpenID 和 Cookies。
- 特殊类型:展示一些不太常见的类型及其使用。 (仍在开发中)
常见问题解答
-
**问题:我能从我的 OpenAPI 文件生成代码吗?**
回答:不能,此软件包仅允许您从您的代码自动生成 OpenAPI 文件。还有其他软件包可以(尝试)做到这一点。所以- Rust 代码(Rocket)--> OpenAPI == Okapi
- OpenAPI --> Rust 代码 != Okapi
-
**问题:我的(diesel)数据库没有实现
OpenApiFromRequest
。**
回答:这是因为参数没有在路径、查询或正文中出现。因此,这被视为一个 请求守卫。有一个 派生宏 用于此,但它不能与#[database)]
宏结合使用。您可以手动实现它,如下所示
为 Diesel DB 实现 `OpenApiFromRequest`
use revolt_rocket_okapi::request::{OpenApiFromRequest, RequestHeaderInput};
use revolt_rocket_okapi::gen::OpenApiGenerator;
use rocket_sync_db_pools::{diesel, database};
#[database("sqlite_logs")]
pub struct MyDB;
impl<'r> OpenApiFromRequest<'r> for MyDB {
fn from_request_input(
_gen: &mut OpenApiGenerator,
_name: String,
_required: bool,
) -> revolt_rocket_okapi::Result<RequestHeaderInput> {
Ok(RequestHeaderInput::None)
}
}
-
**问题:... 不实现
JsonSchema
?**
回答:JsonSchema
实现由Schemars
处理,请确保您已启用其正确的 功能标志。如果它仍然没有实现,请在Schemars
仓库中打开一个问题。 -
**问题:我能向我的 OpenAPI 规范添加自定义数据吗?**
回答:是的,请参阅 自定义模式 示例。如果需要手动合并OpenAPI
对象,Okapi 还提供了内置函数。 -
**问题:我能使用它与其他 Web 框架(如 Rocket)吗?**
回答:是的,但目前没有其他实现。但您可以使用独立的Okapi
软件包,并使用 Serde 创建 json 或 yaml 文件。
功能标志
Okapi
impl_json_schema
:为JsonSchema
和Okapi
类型本身实现。preserve_order
:保持结构字段在Schema
和OpenAPI
文档的所有部分中的顺序。
Rocket-Okapi
preserve_order
:保持结构字段在Schema
和OpenAPI
文档的所有部分中的顺序。swagger
:启用 Swagger UI 以渲染文档。rapidoc
:启用 RapiDoc 以渲染文档。uuid
:在Rocket和Schemars中启用UUID支持。msgpack
:启用Rocket的msgpack支持。(当使用相同的Rocket功能标志时。)secrets
:启用Rocket的secrets支持。(当使用相同的功能标志时。)
请注意,并非所有来自Schemars
的功能标志都被重新导出或启用。因此,如果您有未实现JsonSchema
特质的对象,您可能需要在Schemars
中启用一个功能标志。例如,请参见"uuid"示例。(请确保crate版本匹配)
工作原理
当Rocket服务器启动时,此crate会自动生成一个OpenAPI文件。这里简要描述了其工作方式。
Schemars
crate为我们提供了所有不同结构和枚举的架构。Okapi不直接实现任何架构,这一切都由Schemars
处理。
Okapi
crate仅包含创建OpenAPI文件所需的所有结构。此crate不包含创建它们的任何代码,只包含合并两个OpenAPI
结构的结构和代码。此crate可以重用来在其它Web框架中创建OpenAPI支持。
Rocket-Okapi
crate包含生成OpenAPI文件并一旦生成就提供服务的所有代码。通常使用以下宏执行此代码:mount_endpoints_and_merged_docs!{...}
,openapi_get_routes![...]
,openapi_get_routes_spec![...]
和openapi_get_spec![...]
。
当Rocket服务器启动(或宏放置的位置)时,OpenAPI文件会生成一次。然后,该文件/结构将存储在内存中,并在请求时提供服务。
《Rocket-Okapi-codegen》crate 包含了 derive 宏 的代码。在我们的例子中包括 #[openapi]
,rocket_okapi::openapi_spec![...]
,rocket_okapi::openapi_routes![...]
以及 #[derive(OpenApiFromRequest)]
。由于 Rust 的限制,这需要在一个单独的 crate 中。注意:与 derive
或 codegen
crate 相比,其他 crate 通常更难处理。因此,在更改此处的内容之前,建议先获取一些关于 derive 宏如何工作的经验。
待办事项
- 测试
- 文档
- 基准/优化内存使用和分配
- 为更多 rocket/rocket-contrib 类型实现
OpenApiFrom___
/OpenApiResponder
- 允许自定义 openapi 生成设置,例如:
- 自定义 JSON 模式生成设置
- 更改文档所在路径
许可
本项目采用 MIT 许可证。
对本项目的所有贡献都将采用类似的许可。
依赖项
~8–40MB
~560K SLoC