中集成 Scalar API Reference:Scalar.Azure.Functions 实战指南)
在 Azure FunctionsIsolated Worker中集成 Scalar API ReferenceScalar.Azure.Functions 实战指南【免费下载链接】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本指南以 Scalar 开源仓库中的Scalar.Azure.Functions集成为主线讲解如何在一个 Azure Functions 独立工作进程isolated worker应用中渲染基于 OpenAPI/Swagger 文档的 Scalar API Reference。读完本文你将掌握包的安装与依赖选择、ASP.NET Core 集成模型与内置HttpRequestData两种 HTTP 模型的完整接入方式、OpenAPI 文档路由与RoutePrefix的对齐技巧、按请求动态配置以及请求分发、静态资源、缓存协商等底层实现原理。认识Scalar.Azure.FunctionsScalar.Azure.Functions是 Scalar 为 Azure Functions 提供的 NuGet 集成包目标是在函数应用中直接渲染 Scalar API Reference 页面。它只支持 isolated worker 模型并同时兼容 Azure Functions 的两种 HTTP 模型见 getting-started.mdASP.NET Core 集成模型HttpContext/HttpRequest——官方推荐内置 HTTP 模型HttpRequestData/HttpResponseData——见 built-in-http-model.md。[!NOTE]in-process 模型不受支持。该模型已于 2026 年 11 月停止支持见 limitations.md因此新项目应优先采用 isolated worker。从 CHANGELOG.md 可以看到该集成的发展脉络0.2.0 首次加入Scalar.Azure.Functions同时支持两种 HTTP 模型后续版本将请求处理器、渲染结果与静态资源表抽入共享项目以SCALAR_SERVERLESS编译常量复用给Scalar.Aws.Lambda对Scalar.Azure.Functions的公共 API 与行为无破坏。快速开始使用 ASP.NET Core 集成模型1. 安装包在函数项目目录执行dotnet add package Scalar.Azure.Functions同时需要安装对应 HTTP 模型的 Azure Functions 扩展。使用 ASP.NET Core 集成模型时dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore2. 注册服务在Program.cs中启用 ASP.NET Core 集成并注册 Scalar 服务。参考 Playground 的 Program.csusing Microsoft.Azure.Functions.Worker.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Scalar.Azure.Functions; var builder FunctionsApplication.CreateBuilder(args); builder.ConfigureFunctionsWebApplication(); builder.Services.AddScalarApiReference(options { options.Title My API; }); builder.Build().Run();AddScalarApiReference是定义在 ScalarServiceCollectionExtensions.cs 中的扩展方法它通过services.Configure(configureOptions)注入配置委托再以TryAddScopedIScalarApiReference, ScalarApiReference()将IScalarApiReference注册为scoped 作用域服务因此你可以在每个 HTTP 触发器中安全地注入并解析它。3. 添加函数并转发请求注入IScalarApiReference声明一个 catch-all HTTP 触发器并把请求转发给它。参考 Playground 的 ScalarFunction.csusing Microsoft.AspNetCore.Http; using Microsoft.Azure.Functions.Worker; using Scalar.Azure.Functions; public class ScalarFunction(IScalarApiReference scalar) { [Function(ScalarApiReference)] public Task Run( [HttpTrigger(AuthorizationLevel.Anonymous, get, Route scalar/{*path})] HttpRequest request) scalar.HandleAsync(request.HttpContext); }[!IMPORTANT] catch-all 路由参数必须命名为path如Route scalar/{*path}。处理器依赖它来区分静态资源请求与参考页面请求并解析文档名详见 limitations.md。使用默认的 Azure Functions 路由前缀api时参考页面将托管在/api/scalar/下。4. 指向你的 OpenAPI 文档默认情况下Scalar 会在参考页面的相对路径openapi/{documentName}.json处寻找 OpenAPI 文档。你可以把文档暴露在该路由下或者通过AddDocument修改匹配模式builder.Services.AddScalarApiReference(options { options.AddDocument(v1, routePattern: openapi/v1.json); });相对文档 URL 会在浏览器端基于参考页面的基准路径解析因此无论宿主使用了什么路由前缀或部署在子路径下它都能正常工作。Playground 中的 WeatherFunctions.cs 给出了一个完整的落地示例它声明了一个openapi/{documentName}.json路由的OpenApiDocument函数直接返回一段 OpenAPI 3.1.0 文档含/weather路径与WeatherForecastschema并在文档的servers中声明{ url: /api }与默认路由前缀对齐——这正是一个函数即 API 函数即文档的最小闭环。5. 对齐RoutePrefixScalar 默认假定 Azure Functions 的 HTTP 路由前缀是api对应host.json中的routePrefix: api可参考 host.json。如果你在host.json中改了前缀需要在 Scalar 选项中同步builder.Services.AddScalarApiReference(options { options.RoutePrefix functions; });如果禁用了 Azure Functions 的路由前缀则设置options.RoutePrefix null。RoutePrefix定义在 ScalarOptions.AzureFunctions.cs 中默认值为api。它的作用是让 Scalar 用与宿主相同的路由前缀来解析相对文档与配置 URL保证浏览器端拼接出的地址与函数实际暴露的地址一致。需要特别说明的是RoutePrefix只影响参考页面生成的客户端基准路径不影响你的函数路由声明本身。使用内置 HTTP 模型HttpRequestData如果你的函数应用使用内置的 Azure Functions HTTP 模型而不是 ASP.NET Core 集成请改用IScalarApiReference.HandleAsync的HttpRequestData重载它会返回一个HttpResponseData直接作为函数返回值。Program.cs与 ASP.NET Core 模型不同这里使用ConfigureFunctionsWorkerDefaults()而不是ConfigureFunctionsWebApplication()using Microsoft.Azure.Functions.Worker.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Scalar.Azure.Functions; var builder FunctionsApplication.CreateBuilder(args); builder.ConfigureFunctionsWorkerDefaults(); builder.Services.AddScalarApiReference(options { options.Title My API; }); builder.Build().Run();函数定义using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Scalar.Azure.Functions; public class ScalarFunction(IScalarApiReference scalar) { [Function(ScalarApiReference)] public TaskHttpResponseData Run( [HttpTrigger(AuthorizationLevel.Anonymous, get, Route scalar/{*path})] HttpRequestData request) scalar.HandleAsync(request); }与 ASP.NET Core 集成模型一致catch-all 路由参数必须命名为path。处理器会从函数绑定数据binding data中读取该值来解析静态资源与文档名。IScalarApiReference接口的两个重载定义在 IScalarApiReference.csTaskHttpResponseData HandleAsync(HttpRequestData request, ActionScalarOptions, HttpRequestData? configureOptions null)——内置 HTTP 模型Task HandleAsync(HttpContext httpContext, ActionScalarOptions, HttpContext? configureOptions null)——ASP.NET Core 集成模型响应直接写入HttpResponse。按请求动态配置HandleAsync的可选回调允许你针对每个请求定制选项例如根据HttpContext动态改变标题[Function(ScalarApiReference)] public Task Run( [HttpTrigger(AuthorizationLevel.Anonymous, get, Route scalar/{*path})] HttpRequest request) scalar.HandleAsync(request.HttpContext, (options, context) { options.Title $My API ({context.Request.Host}); });内置 HTTP 模型同样支持按请求配置[Function(ScalarApiReference)] public TaskHttpResponseData Run( [HttpTrigger(AuthorizationLevel.Anonymous, get, Route scalar/{*path})] HttpRequestData request) scalar.HandleAsync(request, (options, req) { options.Title My API; });这个回调在 ScalarApiReference.cs 中于请求处理前被调用其执行的时机在读取IOptionsSnapshotScalarOptions之后、调用ScalarRequestProcessor.Process之前因此对单次请求是幂等且隔离的不会污染后续请求的配置。多文档与AddDocument完整签名如果你的 API 有多个 OpenAPI 文档例如 v1、v2可以在注册时一次性加入。AddDocument的完整签名定义在共享项目 ScalarOptionsExtensions.cs 中public static TOptions AddDocumentTOptions( this TOptions options, string documentName, string? title null, string? routePattern null, bool isDefault false, string? agentKey null) where TOptions : ScalarOptions各参数含义如下参数说明documentName文档标识名会替换OpenApiRoutePattern中的{documentName}占位符title文档显示标题不传时默认使用文档名routePattern该文档的 OpenAPI 路由模式不传时使用全局OpenApiRoutePattern可含{documentName}占位符isDefault多文档时是否作为默认选中项仅应有一个文档标记为 trueagentKey可选的 Agent Scalar 密钥另外还有AddDocuments重载可传文档名集合或ScalarDocument集合。当添加多个文档时它们会以下拉菜单的形式展示在参考页面中如果没有任何显式文档默认会使用名为v1的文档。请求处理管线源码剖析ScalarApiReference的两个重载最终都会把参数归一化后交给托管无关的ScalarRequestProcessor.Process共享项目中的 ScalarRequestProcessor.cs。理解这条管线有助于排查页面打不开资源 404缓存不生效等问题1. 静态资源分发。当 catch-all 剩余路径非空且匹配已知资源类型时直接返回静态资源流若资源未知则返回 404。仓库内置的静态资源包括scalar.azure.functions.js、scalar.js、favicon.svg等见src/Scalar.Azure.Functions/StaticAssets/目录。2. 尾部斜杠重定向。当请求的是无尾部斜杠的索引路径如/api/scalar时返回 302 重定向到/api/scalar/确保浏览器端相对资源 URL 能正确解析。测试 ScalarRequestProcessorTests.cs 验证了Process(/api/scalar, ...)会得到状态码 302 与Location: scalar/。3. ETag / 304 协商。静态资源请求携带If-None-Match且与资源 ETag 匹配时返回 304 Not Modified并带上Cache-Control: no-cache与Vary: Accept-Encoding。对应测试验证了首次请求后携带 ETag 的第二次请求会命中 304见同文件第 138 行起的Process_ShouldReturnNotModified_WhenETagMatches。4. 文档名解析。如果路由剩余部分非空处理器会清空现有文档并用该值作为唯一文档名options.AddDocument(remainder)否则在无任何文档时回退到v1。测试Process_ShouldUseDocumentNameFromRoute_WhenProvided验证了请求/api/scalar/v3时 HTML 中只包含openapi/v3.json。5. 客户端基准路径。渲染 HTML 时处理器会结合RoutePrefix与完整请求路径生成客户端基准路径。仓库测试断言请求路径为/api/scalar/时HTML 中出现的基准路径是/scalar/而不是/api/scalar/见 ScalarRequestProcessorTests.cs这正是相对 URL 在浏览器端基于参考页面的基准路径解析的代码级体现。6. CSP nonce。若options.DynamicNonce开启每次请求会生成一个随机 nonce 注入 HTML并将其写入HttpContext.Items键为ScalarOptions.NonceHttpContextItemKey供后续 CSP 校验使用。7. 响应写入。两种 HTTP 模型的响应写入逻辑分别位于 ScalarApiReference.cs两者都会处理重定向、304、404、Cache-Control、ETag、Content-Encodinggzip与Content-Type头HTML 与静态资源流会分别写入响应体。此外内置模型下从绑定数据读取的路由值可能带有 JSON 引号代码会通过Trim()做归一化处理见第 191-200 行。测试与验证仓库为Scalar.Azure.Functions提供了完整的测试覆盖主要位于 tests/Scalar.Azure.Functions.TestsScalarRequestProcessorTests.cs覆盖索引请求返回包含div idapp/div的 HTML、默认文档回退到openapi/v1.json、路由文档名解析、无斜杠 302 重定向、静态资源scalar.azure.functions.js、scalar.js、favicon.svg的正确 Content-Type 与 ETag、ETag 命中时的 304、CSP nonce 注入、自定义标题与多文档等场景ScalarApiReferenceHttpRequestDataTests.cs通过FakeFunctionContext、FakeHttpRequestData等测试替身见 TestDoubles走通内置 HTTP 模型全链路手工构造HttpResponseData状态码、请求头、流拷贝ScalarApiReferenceHttpContextTests覆盖 ASP.NET Core 集成模型路径。如果你是维护者或希望深度定制这些测试既是行为契约也是排查集成问题的第一手资料。限制与路线图了解以下限制可以帮你提前规避集成中的坑详见 limitations.md1. 你必须自己提供函数。与 ASP.NET Core 集成MapScalarApiReference()自动注册端点不同本包要求你自行声明一个小的 HTTP 触发器函数并把请求转发给IScalarApiReference。这是首版的刻意设计若把开箱即用的[Function]直接打进包里将依赖 Azure Functions worker SDK 的源生成器在被引用的程序集中发现[Function]方法而这默认并不可靠显式处理器则能稳定地同时工作于两种 HTTP 模型从而绕开该限制。路线图显示团队正在评估零样板模式无需手写函数待跨程序集函数发现能力可以干净地启用后可能在后续版本加入。2. 路由参数名必须为path。catch-all 参数名写错将导致处理器无法区分静态资源请求与参考页面请求、无法解析文档名。3. 仅支持 isolated worker。in-process 模型不受支持2026 年 11 月停止支持。小结把Scalar.Azure.Functions接进函数应用的完整链路是安装包 →ConfigureFunctionsWebApplication()或ConfigureFunctionsWorkerDefaults()→AddScalarApiReference(options)注册服务 → 声明路由为scalar/{*path}的 catch-all 函数并转发给IScalarApiReference.HandleAsync→ 在openapi/{documentName}.json暴露你的 OpenAPI 文档并按需通过AddDocument、RoutePrefix与按请求回调微调行为。掌握这套流程后你的 Azure Functions API 就能获得与 Scalar 其他 .NET 集成一致的现代化 API 参考体验。更多配置选项可继续阅读仓库内 docs 目录 下的各篇文档并参考 Playground 示例 直接运行验证。【免费下载链接】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),仅供参考