资讯动态

Scalar 与 Rust Aide 集成实战:在 Axum 与 Actix 中渲染交互式 OpenAPI 文档

发布时间:2026/9/14 3:47:39 来源:尧图企业网站定制
Scalar 与 Rust Aide 集成实战在 Axum 与 Actix 中渲染交互式 OpenAPI 文档【免费下载链接】scalarScalar is an open-source API platform: Modern REST API Client Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalarScalar 是开源 API 平台Aide 是 Rust 生态中流行的 OpenAPI 文档生成库两者结合可以让 Rust 服务在运行时直接生成 OpenAPI 文件并以内置路由的形式提供美观、可交互的 API 参考页面。本文基于仓库中 Aide 集成文档 展开先给出 Aide 在 Axum 中的官方内置集成用法再覆盖 Actix 等框架下通过scalar-doccrate 接入 Scalar 的完整步骤并结合仓库内的官方 Rust crate integrations/rust 源码深入解析 Scalar 页面在 Rust 服务中的渲染机制与配置项。背景Aide 负责“生成”Scalar 负责“呈现”在 Rust 项目中OpenAPI 文档通常分两层文档生成层Aide 通过分析ApiRouter等类型在编译期/运行期推导出符合 OpenAPI 规范的 JSON 文档并将其暴露为路由例如/docs/private/api.json文档呈现层Scalar 读取这份 OpenAPI 文档渲染出带侧边栏、主题切换和调试能力的交互式 API 参考页面。Scalar 对 Rust 生态提供三条接入路径Aide 文档 覆盖其中前两条Aide 自带的aide::scalar::Scalar面向 Axum最省事社区 cratescalar-doc框架无关支持 Actix 等Scalar 仓库维护的官方 cratescalar_api_reference源码位于 integrations/rust同时支持 Axum、Actix-web、Warp详见 integrations/rust 文档。在 Axum 中使用 Aide 内置的 Scalar 集成Aide 内置了 Scalar 集成只需把文档路由api_route设置为Scalar类型即可。完整示例继承自 Aide 集成文档use aide::{ axum::{ routing::{get_with}, ApiRouter, IntoApiResponse, }, openapi::OpenApi, scalar::Scalar, }; // … let router: ApiRouter ApiRouter::new() .api_route_with( /, get_with( Scalar::new(/docs/private/api.json) .with_title(Aide Axum) .axum_handler(), |op| op.description(This documentation page.), ), |p| p.security_requirement(ApiKey), ) // …要点拆解Scalar::new(/docs/private/api.json)第一个参数是 OpenAPI 文档的 URL 或路径。Aide 会把生成的 OpenAPI JSON 发布到该地址Scalar 页面加载时从该地址拉取文档。也就是说你的 Axum 应用中需要存在两个路由文档页/与 OpenAPI 文档/docs/private/api.json.with_title(Aide Axum)设置文档页标题.axum_handler()把Scalar配置转换为标准的 Axum 响应 handler挂到get_with上|p| p.security_requirement(ApiKey)在参数层为该文档页附加ApiKey安全要求配合你项目中的securitySchemes使用|op| op.description(...)为文档页本身在 OpenAPI 中补充描述。这种写法的优势是文档页与 API 路由同属一个ApiRouterAide 生成的 OpenAPI 文档也会包含该文档页自身的描述无需额外手工维护。非 Axum 框架用 scalar-doc 在 Actix 中接入 Scalar如果项目使用 Actix 或其他 Web 框架Aide 文档给出的方案是社区 cratescalar-doc框架无关。步骤安装 crate 并启用actixfeaturecargo add scalar-doc -F actix编写文档页与 OpenAPI 文档两个 handler示例继承自 Aide 集成文档use actix_web::{get, App, HttpResponse, HttpServer, Responder}; use scalar_doc::scalar_actix::ActixDocumentation; #[get(/)] async fn doc() - impl Responder { ActixDocumentation::new(Api Documentation title, /openapi) .theme(scalar_doc::Theme::Kepler) .service() } #[get(/openapi)] async fn openapi() - impl Responder { let open include_str!(openapi.json); HttpResponse::Ok().body(open) } #[actix_web::main] async fn main() - std::io::Result() { HttpServer::new(|| App::new().service(doc).service(openapi)) .bind((127.0.0.1, 8080))? .run() .await }逐行说明ActixDocumentation::new(Api Documentation title, /openapi)第一个参数为页面标题第二个参数为 OpenAPI 文档地址——与上面 Axum 示例中Scalar::new(...)的角色完全一致即“页面路由 文档 URL”两段式结构.theme(scalar_doc::Theme::Kepler)显式指定 Scalar 主题KeplerScalar 支持多套主题.service()转换为 Actix 可挂载的 serviceinclude_str!(openapi.json)把 OpenAPI JSON 直接编译进二进制/openapi路由在运行时原样返回。注意此处是静态文件内嵌与 Aide 的动态生成不同——scalar-doc路线下你可以自由选择文档来源静态 JSON、utoipa动态生成等均可。仓库官方 cratescalar_api_reference同一套渲染内核除了 Aide 与scalar-docScalar 仓库自身在 integrations/rust 下维护了官方 cratescalar_api_reference可作为理解“Scalar 页面到底如何在 Rust 服务中被渲染”的参照实现。依赖与 feature 划分从 Cargo.toml 可以看到 crate 的核心依赖只有rust-embed、serde、serde_json三个 Web 框架均为可选 feature[features] default [] axum [dep:axum, dep:axum-extra, dep:tokio] actix-web [dep:actix-web] warp [dep:warp, dep:tokio]按需开启 feature 即可避免引入无关框架依赖# 在你的 Cargo.toml 中 [dependencies] scalar_api_reference { version 0.1.0, features [axum] } serde_json 1.0仓库提供了与 feature 一一对应的可运行示例examples/axum.rs、examples/actix.rs、examples/warp.rs对应的运行命令见 package.json 中的 scripts 定义cargo run --example axum --features axum # http://localhost:3000/scalar cargo run --example actix --features actix-web # http://localhost:8080/scalar cargo run --example warp --features warp # http://localhost:3030/scalarAxum 示例的最小调用examples/axum.rsuse axum::Router; use scalar_api_reference::axum::router; use serde_json::json; #[tokio::main] async fn main() { let config json!({ url: https://registry.scalar.com/scalar/apis/galaxy?formatjson, theme: purple, }); let app Router::new().merge(router(/scalar, config)); let listener tokio::net::TcpListener::bind(0.0.0.0:3000).await.unwrap(); println!(Server running on http://localhost:3000/scalar); axum::serve(listener, app).await.unwrap(); }router(/scalar, config)一行同时注册了两个路由/scalar文档页 HTML与/scalar/scalar.js前端 JS 包后文源码分析会解释这个设计。渲染机制模板替换 内嵌静态资源从 src/lib.rs 的源码结构看整个渲染内核由三部分构成1编译期内嵌静态资源。crate 用rust-embed把ui/目录打进二进制lib.rs 第 810 行#[derive(RustEmbed)] #[folder ui/] struct Assets; pub fn get_asset_with_mime(path: str) - Option(String, Vecu8) { ... }因此部署时不再依赖外部静态目录scalar.js直接从内存读取并由get_mime_type按扩展名映射 MIME 类型html/js/css/json/png/svg/ico未知类型回退为application/octet-stream。2HTML 模板占位符替换。文档页 HTML 模板 ui/index.html 只有 20 多行包含两个占位符script src__JS_BUNDLE_URL__/script script Scalar.createApiReference(#app, __CONFIGURATION__) /script渲染函数lib.rs 第 3945 行做两次字符串替换pub fn render_scalar(config_json: str, js_bundle_url: Optionstr) - String { let html_template include_str!(../ui/index.html); let js_url js_bundle_url.unwrap_or(https://cdn.jsdelivr.net/npm/scalar/api-reference); html_template .replace(__CONFIGURATION__, config_json) .replace(__JS_BUNDLE_URL__, js_url) }这解释了前面示例中两条路由的存在意义router(path, config)会传Some({path}/scalar.js)作为js_bundle_url让页面从本服务的/scalar/scalar.js加载前端包实现完全自托管、离线可用不传None时回退到 CDN 上的scalar/api-reference包。测试用例 test_scalar_html_generation 对两种模式都做了断言。3对外 API 分层。核心函数按“框架无关 → 框架专用”分层函数/模块作用scalar_html(config, js_bundle_url)返回渲染后的 HTML 字符串核心入口scalar_html_default(config)/scalar_html_from_json(_default)使用 CDN 的便捷函数JSON 字符串版本会先serde_json解析非法 JSON 返回Errget_asset/get_asset_with_mime读取内嵌的scalar.js、index.html等静态资源axum::router/axum::routes/axum::scalar_responseAxum 路由与响应构造routes返回文档页与 JS 资源两条独立路由actix_web::config/actix_web::scalar_responseActix 的ServiceConfig闭包与响应构造warp::routes/warp::separate_routes/warp::scalar_replyWarp filter注意 Warp 路径约定不带前导斜杠用scalar而非/scalar资源路由按“更具体路由优先”排列以避免冲突每个框架模块都通过#[cfg(feature ...)]条件编译lib.rs 第 71 行起未启用的框架零成本。配置项JSON 配置如何映射到页面配置以serde_json::Value传入字段即 Scalar 前端createApiReference的选项。从示例与测试用例可以确认以下常用字段let config json!({ url: /openapi.json, // OpenAPI 文档地址Aide 生成的 JSON 路由 theme: kepler, // 主题如 purple / kepler layout: classic // 布局warp 示例中出现 });多文档场景使用sources数组。crate 还为此提供了类型安全的构造类型 src/config.rsuse scalar_api_reference::{AgentOptions, Source}; let sources vec![ Source::new(https://api.example.com/v1.json) .with_agent(AgentOptions::with_key(your-api-key)), Source::new(https://api.example.com/v2.json), ]; let config json!({ sources: serde_json::to_value(sources).unwrap() });其中AgentOptions对应 AI 助手Agent Scalar选项with_key(...)设置生产环境必需的 API keydisabled()则序列化为disabled: true关闭该功能Source表示一份 OpenAPI 文档url为文档地址、agent为按文档粒度的助手选项。测试 test_sources_with_agent_in_config 验证了sources 每源 key 会被正确注入到 HTML 中。验证与测试官方 crate 的测试均位于 src/lib.rs覆盖了渲染链路的关键点可作为集成自测的参照test_scalar_html_generation断言渲染结果包含url、theme、自定义 JS 包地址及完整的html结构CDN 回退地址也在断言中test_error_handling缺失右括号的非法 JSON 使scalar_html_from_json返回Err空配置{}仍能成功渲染test_get_asset_with_mime确认index.html与scalar.js可从内嵌资源中取出且 MIME 分别为text/html与application/javascript各框架模块测试axum_tests/actix_tests/warp_tests在对应 feature 开启时编译执行验证响应构造与路由创建不产生错误。运行方式在 integrations/rust 目录下命令取自 package.jsoncargo test --features axum cargo test --features actix-web cargo test --features warp三种方案如何选择场景推荐方案依据Axum Aide 生成 OpenAPIaide::scalar::ScalarAide 内置文档路由与 API 路由同在一个ApiRouter最简洁见 Aide 集成文档Actix / 其他框架 任意文档来源scalar-doccrate框架无关ActixDocumentation::new(标题, 文档URL)两段式接入Axum / Actix / Warp 完全自托管官方scalar_api_referencecrate资产内嵌二进制、MIME 自动处理、多文档与 Agent 类型安全配置源码见 integrations/rust/src/lib.rs需要说明的适用前提aide::scalar::Scalar与scalar-doc为仓库外的第三方 crate本文代码以 Aide 集成文档 记录的用法为准升级时请以对应 crate 的最新文档核对 API而scalar_api_reference的版本与 API 以仓库内 Cargo.toml版本 0.1.0及 CHANGELOG 为准。无论采用哪条路径Scalar 侧的配置模型是一致的一个页面路由、一个可访问的 OpenAPI 文档地址、可选的theme/layout/sources等选项——理解这一点后切换框架或方案的成本都很低。【免费下载链接】scalarScalar is an open-source API platform: Modern REST API Client Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价