
在 AWS Lambda 中托管 Scalar API 参考文档Scalar.Aws.Lambda 集成实战指南【免费下载链接】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.Aws.LambdaNuGet 包展开讲解如何让一个由 Amazon API Gateway HTTP API 前置的 AWS Lambda 函数直接渲染出完整的 Scalar API Reference 界面。读完本文你将掌握包的安装与两种接入方式零依赖静态工厂与依赖注入宿主、API Gateway 路由与{proxy}贪婪匹配的声明方式、OpenAPI 文档的暴露与寻址规则以及 Stage 前缀自动剥离、自定义域名 base path、按请求动态配置等生产环境常见问题的处理方案。1. 适用场景与前置约束Scalar.Aws.Lambda的定位非常聚焦在AWS Lambda 函数中渲染 Scalar API 参考文档且该函数必须由Amazon API Gateway HTTP API前置并使用payload format 2.0事件模型即请求与响应类型分别为APIGatewayHttpApiV2ProxyRequest/APIGatewayHttpApiV2ProxyResponse位于Amazon.Lambda.APIGatewayEvents。这一点与 ASP.NET Core 集成不同Scalar.AspNetCore可以通过MapScalarApiReference()替你注册端点而Scalar.Aws.Lambda要求你自己声明 Lambda 函数再把请求转发给包提供的处理器详见下文两种入口行为上更接近 Azure Functions 集成。需要特别注意当前版本仅支持 API Gateway HTTP API。以下事件源不在支持范围内详见 limitations.mdAPI Gateway REST APIpayload format 1.0对应APIGatewayProxyRequest/APIGatewayProxyResponseApplication Load BalancerALB目标组Lambda Function URLs。官方说明中给出的原因是这些事件形状在路由/路径参数解析、Header 结构、Stage 处理上与 HTTP API 差异过大值得为它们单独设计适配器而非做一个尽力而为的兼容层——这是明确的 roadmap 项。如果你今天就面临这些场景有两个替代路径一是直接调用Scalar.Shared中与ScalarRequestProcessor等价的底层构建块自行处理二是如果你在 Lambda 里托管的是完整 ASP.NET Core 应用通过Amazon.Lambda.AspNetCoreServer应改用Scalar.AspNetCore包的MapScalarApiReference()。2. 安装 NuGet 包在任意 .NET 项目中执行dotnet add package Scalar.Aws.Lambda从项目文件 Scalar.Aws.Lambda.csproj 可以看到该包目标框架为net8.0;net9.0;net10.0依赖Amazon.Lambda.Core、Amazon.Lambda.APIGatewayEvents、Microsoft.Extensions.DependencyInjection.Abstractions与Microsoft.Extensions.Options。值得一提的实现细节包内的静态资源scalar.js、scalar.aws.lambda.js、favicon.svg等是作为EmbeddedResource 内嵌进程序集的Release 配置下会优先打包.gz压缩资源scalar.js.gz以原始文件名scalar.js发布Debug 配置下则回退到未压缩文件Release 下若压缩产物缺失同样会回退。这意味着部署产物自包含、无需额外 CDN 或 S3 托管静态文件函数包本身就是完整的。3. 选择入口两种等效的接入方式Scalar.Aws.Lambda提供两个共享同一套底层实现的入口都由核心类型ScalarApiReference承载传输逻辑按你函数的托管方式二选一即可。Option A — 零 DI 静态工厂推荐用于普通 Lambda 函数对于没有依赖注入容器的普通 Lambda 函数例如 .NET 8 的可执行程序集/顶层语句风格ScalarApiReferenceHandler.Create(...)直接返回一个可直接用作 Lambda 入口的 request/response 委托using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.RuntimeSupport; using Amazon.Lambda.Serialization.SystemTextJson; using Scalar.Aws.Lambda; var handler ScalarApiReferenceHandler.Create(options { options.Title My API; }); await LambdaBootstrapBuilder.CreateAPIGatewayHttpApiV2ProxyRequest, APIGatewayHttpApiV2ProxyResponse(handler, new DefaultLambdaJsonSerializer()) .Build() .RunAsync();从源码 ScalarApiReferenceHandler.cs 看Create()内部构造了一个ScalarApiReference实例并通过一个私有的StaticOptionsSnapshot一个最小化的IOptionsSnapshotScalarOptions适配器在每次访问时构建全新的ScalarOptions从而在无 DI 环境下复刻IOptionsSnapshot的按请求生命周期语义。这保证了两种入口的行为完全一致。该委托的类型签名是FuncAPIGatewayHttpApiV2ProxyRequest, ILambdaContext, TaskAPIGatewayHttpApiV2ProxyResponse因此也可以写成传统方法形态public static Task... Handler(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context) ScalarApiReferenceHandler.Create()(request, context);仓库里的 playground/Function.cs 正是这种可执行程序集风格的完整范例配合 template.yamlHandler: Scalar.Aws.Lambda.Playground、Runtime: dotnet10、Timeout: 10、MemorySize: 256、Architectures: x86_64即可本地 SAM 调试。Option B — 依赖注入推荐用于 Amazon.Lambda.RuntimeSupport 泛型宿主如果你的函数使用Amazon.Lambda.RuntimeSupport的泛型宿主Generic Host把 Scalar 注册为服务再解析IScalarApiReferenceusing Microsoft.Extensions.DependencyInjection; using Scalar.Aws.Lambda; var services new ServiceCollection(); services.AddScalarApiReference(options { options.Title My API; }); await using var provider services.BuildServiceProvider(); // Resolve IScalarApiReference from a scope per invocation, since it is registered scoped. using var scope provider.CreateScope(); var scalar scope.ServiceProvider.GetRequiredServiceIScalarApiReference(); var response await scalar.HandleAsync(request, context);AddScalarApiReference扩展方法定义在 ScalarServiceCollectionExtensions.cs它始终注册ScalarOptions配置即使未传回调也会注册空配置保证IOptionsSnapshotScalarOptions可解析然后TryAddScopedIScalarApiReference, ScalarApiReference()注册服务。接口IScalarApiReference见 IScalarApiReference.cs暴露HandleAsync(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context, ActionScalarOptions, APIGatewayHttpApiV2ProxyRequest? configureOptions null)。[!IMPORTANT]IScalarApiReference以Scoped生命周期注册。请遵循 Lambda DI 的标准实践每次调用新建一个 DI 作用域再解析服务不要从根 provider 直接解析——这正是上面示例代码CreateScope()的用意。4. 声明 API Gateway 路由{proxy}贪婪路径参数路由必须使用{proxy}贪婪路径参数同时为裸索引路径单独声明一条普通路由。以 SAM 模板为例Events: ScalarIndex: Type: HttpApi Properties: Path: /scalar Method: GET ScalarProxy: Type: HttpApi Properties: Path: /scalar/{proxy} Method: ANY为什么必须这样声明因为实现中见 ScalarApiReference.cs通过request.PathParameters[proxy]读取路径剩余部分常量RouteRemainderKey proxy据此区分三类请求GET /scalar与GET /scalar/渲染默认文档的参考索引页GET /scalar/v3渲染名为v3的文档的参考索引页GET /scalar/scalar.js、GET /scalar/scalar.aws.lambda.js、GET /scalar/favicon.svg返回内嵌静态资源。一个健壮性细节如果请求完全没有PathParameters例如函数被直接调用、没有经过 API Gateway 代理集成GetRouteRemainder返回null请求会被当作索引请求处理而不是抛异常。另外注意贪婪参数必须命名为proxy即Path: /scalar/{proxy}适配器据此从request.PathParameters[proxy]取值来区分静态资源请求与参考页请求并解析文档名。路由寻址的完整行为模型参见 http-api-model.md。5. 指向你的 OpenAPI 文档默认情况下Scalar 在参考文档的相对路径下查找openapi/{documentName}.json。你只需把 OpenAPI 文档暴露在对应路由上即可也可以通过AddDocument改变寻址模式options.AddDocument(v1, routePattern: openapi/v1.json);上面的调用把名为v1的文档绑定到openapi/v1.json这个自定义路由模式上。文档名documentName在 URL 中的体现就是第 4 节提到的/scalar/v3这类路径片段——v3即文档名。6. Stage 前缀与自定义域名 base pathAPI Gateway HTTP API 的行为是对于任何命名 Stage非$defaultStage 名会作为路径段出现在RawPath中而特殊的$defaultStage 不会。下表来自 http-api-model.mdStageGET /scalar/对应的RawPath行为$default/scalar/不剥离任何前缀。prod/prod/scalar/自动检测到prod并从渲染出的相对 URL 中剥离。Scalar.Aws.Lambda会自动读取request.RequestContext.Stage自动把 Stage 名折入RoutePrefix前提是你没有显式设置过ScalarOptions.RoutePrefix从而保证prod这类命名 Stage 下渲染出的相对 URL 不会泄漏出多余的/prod/段。实现上对应 ScalarApiReference.cs 的ApplyRoutePrefix方法仅当RoutePrefix为null且 Stage 非空、非$default常量DefaultStageName时才把 Stage 写回options.RoutePrefix。这与 Azure Functions 集成把host.json的routePrefix折入同一选项的处理方式保持一致见 http-api-model.md。但有一个例外场景无法自动处理自定义域名Custom Domain的 base path mapping 对RequestContext.Stage不可见。此时需要显式设置options.RoutePrefix my-base-path;RoutePrefix属性定义于 ScalarOptions.AwsLambda.csnull默认时自动从 Stage 检测显式赋值后优先使用该值。7. 按请求动态配置两种入口都支持可选的配置回调让你在每次请求时覆盖选项// 静态工厂 var handler ScalarApiReferenceHandler.Create(options options.Title My API); // DI var response await scalar.HandleAsync(request, context, (options, req) { options.Title $My API ({req.RequestContext.DomainName}); });DI 路径下这个回调通过IScalarApiReference.HandleAsync的第三个参数传入并在处理请求前被调用configureOptions?.Invoke(options, request)见 ScalarApiReference.cs。注意顺序回调先执行随后才执行 Stage 自动检测ApplyRoutePrefix因此若回调中设置了RoutePrefixStage 检测会被跳过。典型用途包括根据请求的域名/环境动态调整标题、主题或文档内容。8. 底层响应处理与协议细节原理篇把请求转交给ScalarRequestProcessor.Process(...)后ScalarApiReference.HandleAsync依据渲染结果构造APIGatewayHttpApiV2ProxyResponse见 ScalarApiReference.cs 的BuildResponseAsync其状态码语义如下302RedirectLocation非空时返回重定向例如索引页带/不带尾斜杠的规范化跳转并设置Location头304NotModified时返回 304并携带ETag、Cache-Control若内容支持协商还会设置Vary: Accept-Encoding404请求资源不存在时直接返回 404200正常返回携带Cache-Control、ETag、Content-Type等头。8.1 Header 大小写与条件请求API Gateway HTTP API 会把 Header 名转成小写并在headers字段中用逗号合并重复 Header不同于 REST API / payload format 1.0 的multiValueFieldsHTTP API 没有该字段。Scalar.Aws.Lambda以大小写不敏感方式读取Accept-Encoding与If-None-MatchGetHeader内部对每个键做OrdinalIgnoreCase比较因此无论 Header 以何种大小写到达API Gateway 通常会转小写但直接测试调用未必条件请求与 gzip 协商都能正确工作。8.2 响应体编码gzip 与 Base64响应体的编码规则同样定义在BuildResponseAsync中HTML 页面与未压缩静态资源以普通 UTF-8 文本返回IsBase64Encoded falsegzip 压缩的二进制静态资源.gz内嵌资源返回时设置Content-Encoding头body 以Base64 字符串承载且IsBase64Encoded true——这是 Lambda 响应契约对二进制 body 的硬性要求。8.3 静态资源内嵌与压缩静态资源scalar.js、favicon.svg等通过 Scalar.Aws.Lambda.csproj 以 EmbeddedResource 打包Release 下优先打包.gz压缩资源LogicalName 形如ScalarStaticAssets.scalar.jsDebug 下回退未压缩版本同时通过StandaloneJavaScriptFile指向packages/api-reference/dist/browser/standalone.js作为兜底源。这也是为什么函数必须允许客户端发送Accept-Encoding: gzip才能获得压缩资源——AcceptsGzip检查的就是这个头。9. 已知限制与路线图小结最后汇总官方文档明确列出的边界详见 limitations.md函数需自行声明本包不替你注册端点区别于Scalar.AspNetCore必须自己定义 Lambda 函数并转发请求仅支持 HTTP API / payload format 2.0REST APIformat 1.0、ALB、Function URLs 不在首个版本支持范围内属 roadmap 项临时方案是使用Scalar.Shared底层构建块或改用Scalar.AspNetCore贪婪参数必须命名为proxy自定义域名 base path 需显式设置RoutePrefix完整 ASP.NET Core 应用请用Scalar.AspNetCore的MapScalarApiReference()。若想了解版本演进与修复记录可查阅 CHANGELOG.md包的测试覆盖位于 tests/Scalar.Aws.Lambda.Tests可作为理解各入口与路由处理行为的参考完整的本地可运行示例SAM 模板 可执行程序集 输出 API URL见 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),仅供参考