Kong 仓库中的 sam-app:用 AWS SAM 样例无服务器应用为 AWS Lambda 插件搭建本地联调链路
2026/9/10 19:37:32 网站建设 项目流程

Kong 仓库中的 sam-app:用 AWS SAM 样例无服务器应用为 AWS Lambda 插件搭建本地联调链路

【免费下载链接】kong🦍 The API and AI Gateway项目地址: https://gitcode.com/GitHub_Trending/ko/kong

本篇技术指南以 Kong 开源仓库(🦍 The API and AI Gateway)内置的 AWS SAM Hello World 样例工程 spec/fixtures/sam-app 为对象,系统讲解如何借助 SAM CLI 完成这类无服务器应用的本机构建、API 模拟、单元与集成测试及资源清理。与此同时,本指南将结合 Kong 的 AWS Lambda 插件集成测试源码,说明这个“样例应用”在真实仓库中扮演的关键角色——被用来在本地起一个模拟 Lambda 服务,验证 Kong 网关转发 HTTP 请求到 Lambda 函数并正确返回结果的完整链路。读完本文,你将掌握该 fixture 的目录结构、SAM 模板语义、sam local系列命令的用法,以及它在 Kong 仓库中作为联调基准被复用的方式。

sam-app 在仓库中的定位与目录结构

在 Kong 仓库中,spec/fixtures/sam-app 是一个可以随时用 SAM CLI 部署到 AWS 的完整无服务器应用,而不是残缺的测试替身。它的典型用途是配合 Kong 的aws-lambda插件测试:先在本地启动 SAM 模拟的 Lambda 运行时,再让 Kong 将流量转发过去。目录结构如下:

spec/fixtures/sam-app/ ├── hello_world/ # Lambda 函数源码 │ ├── app.py # 函数入口(lambda_handler) │ └── requirements.txt # 函数第三方依赖(requests) ├── events/ │ └── event.json # 可直接注入函数的一次 API Gateway 代理事件样本 ├── tests/ │ ├── unit/ # 单元测试(不依赖 AWS) │ │ ├── test_handler.py │ └── integration/ # 集成测试(需先完成部署) │ ├── test_api_gateway.py ├── template.yaml # SAM 模板:声明 Lambda、API Gateway 等资源 └── README.md # 原始使用说明

各部分的职责可从源码逐一确认:

  • 函数代码:hello_world/app.py 定义了一个符合 API Gateway Lambda 代理输出格式的处理函数lambda_handler(event, context),入参event是描述触发事件的 JSON 字典,返回值包含statusCode与 JSON 编码的body
  • 触发事件样本:events/event.json 是一份典型的 API Gateway 代理集成输入,包含bodyhttpMethodheaderspathParametersqueryStringParametersrequestContext等字段,可直接用于sam local invoke离线触发。
  • 单元测试与集成测试:tests/unit/test_handler.py 直接调用lambda_handler并断言返回结构;tests/integration/test_api_gateway.py 则先通过 boto3 读取已部署 CloudFormation 栈的输出,拿到真实 API Gateway URL 后发起 HTTP 请求。
  • 资源模板:template.yaml 用 SAM(AWS::Serverless-2016-10-31 转换)声明函数与隐式 API。

template.yaml:SAM 模板的核心语义

模板的头部与全局配置揭示了资源的声明方式。Transform: AWS::Serverless-2016-10-31表示这是一个 SAM 模板;Globals可为所有函数统一设置默认属性,例如本样例为每个函数设置了Timeout: 3(超时 3 秒):

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Globals: Function: Timeout: 3 Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.9 Architectures: - x86_64 Events: HelloWorld: Type: Api Properties: Path: /hello Method: get Outputs: HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn

需要重点理解的关键点:

  • AWS::Serverless::Function:SAM 对 CloudFormation 的简化封装。CodeUri指向函数代码目录 hello_world;Handler指明入口app.lambda_handlerRuntime使用python3.9
  • Events触发源:函数定义里的Events属性声明了每个路径的路由与方法。样例中HelloWorld事件把GET /hello关联到该函数,SAM 会据此隐式创建名为ServerlessRestApi的 API Gateway REST API——这也是 README 所说“SAM CLI 读取模板来决定 API 路由及其调用的函数”的机制来源。
  • Outputs:部署完成后输出的三个值分别对应 API Gateway Prod 阶段端点 URL、函数 ARN,以及 SAM 为该函数自动创建的 IAM 角色 ARN。README 中“在部署后的输出值里找到 API Gateway Endpoint URL”指的正是HelloWorldApi

对比之下,真正处理业务逻辑的 app.py 非常精简:返回{"statusCode": 201, "body": {"message": "hello world"}}。需要注意,本仓库内置的这份样例把标准 Hello World 的状态码改成了201,这是为了配合 Kong 侧测试验证“代理集成模式能原样透传 Lambda 的 201 状态码”(详见下文“与 Kong AWS Lambda 插件的集成测试”一节)。

环境准备与本机构建部署

要使用 SAM CLI 处理这个样例工程,README 列出的前置条件包括:

  • SAM CLI(Serverless Application Model 命令行工具,是 AWS CLI 对 Lambda 构建、测试能力的扩展);
  • Python 3 运行时;
  • Docker(SAM CLI 借助 Docker 在模拟 Lambda 的 Amazon Linux 环境中运行函数,并模拟应用的构建环境与 API)。

这些前置要求可以通过仓库中的辅助代码得到印证:spec/fixtures/aws-sam.lua 在执行联调前会用sam --version探测 SAM CLI 是否已安装,用uname -m判断操作系统架构,并明确 SAM 本地运行只支持 x86_64/arm64,故对应的集成测试在aarch64机器上会被跳过。

首次构建与部署分两步进行:

sam build --use-container sam deploy --guided

第一条命令会在容器内完成函数依赖安装(读取 hello_world/requirements.txt)并生成部署包;第二条命令将应用打包部署到 AWS,过程中会以向导形式逐个询问以下配置:

  • Stack Name:部署到 CloudFormation 的栈名,须在账户与区域内唯一,推荐直接使用项目名(本样例 README 与清理命令均默认栈名为sam-app)。
  • AWS Region:目标部署区域。
  • Confirm changes before deploy:设为yes时,任何变更集在执行前都会展示给用户做人工确认;设为no时 SAM CLI 自动应用变更。
  • Allow SAM CLI IAM role creation:多数 SAM 模板(含本样例)会创建供 Lambda 访问 AWS 服务的最小权限 IAM 角色。要部署会创建或修改 IAM 角色的 CloudFormation 栈,必须提供CAPABILITY_IAM。若在该提示处不授予权限,则需显式携带--capabilities CAPABILITY_IAM重跑sam deploy
  • Save arguments to samconfig.toml:设为yes会把本次选择保存到项目内的配置文件,之后直接执行sam deploy即可复用参数、完成增量更新。

部署完成后,在输出值(Outputs)中可以找到 template.yaml 里HelloWorldApi声明的 API Gateway 端点 URL。

使用 sam local 在本地构建、调用与模拟 API

SAM CLI 的价值在于“不部署也能跑”:spec/fixtures/aws-sam.lua 的start_local_lambda()实际执行的正是下面这条等价命令:

sam local start-lambda --template-file spec/fixtures/sam-app/template.yaml --port <动态空闲端口>

构建本地版本并直接以测试事件调用单个函数:

sam-app$ sam build --use-container sam-app$ sam local invoke HelloWorldFunction --event events/event.json

其中--event events/event.json指向 events/event.json。该事件模拟的是 API Gateway 代理集成格式:函数收到的event里包含请求方法、路径、请求头、查询参数、stage 变量与requestContext上下文,body字段预置了{"message": "hello world"}。由于 app.py 返回状态码201,本地直接调用会看到 201 与对应 JSON 响应。

SAM CLI 还能模拟整个 API。使用sam local start-api在 3000 端口启动本地 API 网关:

sam-app$ sam local start-api sam-app$ curl http://localhost:3000/

这里有个值得注意的细节:start-api依据模板中的Events定义来决定路由映射。本样例模板只声明了GET /hello(见 template.yaml 中Events.HelloWorld.PropertiesPath: /helloMethod: get),因此如需实际命中该函数,curl 地址应相应调整为:

sam-app$ curl http://localhost:3000/hello

无论用哪种方式,SAM CLI 都会读取应用模板来确定 API 路由及每个路径对应调用的函数,其映射关系正来自函数定义中的如下片段:

Events: HelloWorld: Type: Api Properties: Path: /hello Method: get

与 Kong AWS Lambda 插件的集成测试:fixture 的真实用途

这是本仓库使用 sam-app 的核心场景。Kong 把 spec/fixtures/sam-app/template.yaml 当作 AWS Lambda 插件集成测试的后端桩服务,完整调用链记录在 spec/03-plugins/27-aws-lambda/08-sam-integration_spec.lua 与辅助模块 spec/fixtures/aws-sam.lua 中:

  1. 启动模拟 Lambda 服务aws-sam.luastart_local_lambda()通过ngx.pipe.spawn后台拉起sam local start-lambda,指定--template-file spec/fixtures/sam-app/template.yaml并绑定一个动态获取的空闲端口(helpers.get_available_port())。
  2. 等待服务就绪:测试用curl -s http://localhost:<port>/2015-03-31/functions/HelloWorldFunction/invocations -d '{}'轮询调用模拟的HelloWorldFunction,直到返回成功(最长等待 1200 秒)。该端点与真实 Lambda 的InvokeAPI 兼容,{}即函数入参事件。
  3. 配置 Kong 路由与 aws-lambda 插件:测试基于 DB 策略创建两条不同 host 的路由,并分别挂上aws-lambda插件,配置指向本地模拟服务:
bp.plugins:insert { name = "aws-lambda", route = { id = route.id }, config = { host = "localhost", port = sam_port, -- 模拟 Lambda 服务端口 disable_https = true, -- 本地为 HTTP,不启用 HTTPS aws_key = "mock-key", -- 本地测试用占位凭证 aws_secret = "mock-secret", aws_region = "us-east-1", function_name = "HelloWorldFunction", log_type = "None", is_proxy_integration = true, -- 是否按代理集成解析返回体 }, }
  1. 断言代理结果:测试对lambda.test(非代理集成)与lambda2.testis_proxy_integration = true)分别发起带对应 Host 头的 GET 请求:
    • 普通调用路径断言响应为200(Kong 仅转发,不解析 Lambda 返回体);
    • 代理集成路径断言响应为201且 JSON 体中的message等于"hello world"——这正是 app.py 返回201的原因:验证 Kong 在代理模式下能把 Lambda 返回的状态码与消息体原样带回给客户端。

这一节也解释了为什么测试中同时出现HelloWorldFunction这个函数名:它正是 template.yaml 中声明的资源逻辑 ID。插件配置项(如is_proxy_integrationdisable_httpslog_type等)的更完整定义可继续阅读 kong/plugins/aws-lambda/schema.lua 与其执行逻辑 kong/plugins/aws-lambda/handler.lua。

运行单元测试与集成测试

测试代码按“离线/在线”分为两级。先安装测试依赖再跑单元测试:

sam-app$ pip install -r tests/requirements.txt --user # 单元测试(无需部署) sam-app$ python -m pytest tests/unit -v

依赖清单见 tests/requirements.txt(pytestboto3requests)。单元测试 tests/unit/test_handler.py 构造一份 API Gateway 代理事件字典后直接调用app.lambda_handler,并断言返回体中存在message字段。

集成测试则要求先完成真实部署,并以环境变量注入栈名:

sam-app$ AWS_SAM_STACK_NAME=<stack-name> python -m pytest tests/integration -v

tests/integration/test_api_gateway.py 展示了集成测试的常见模式:fixtureapi_gateway_url读取环境变量AWS_SAM_STACK_NAME,若未设置会抛出带有提示信息的ValueError;随后用 boto3 的 CloudFormation 客户端describe_stacks拉取该栈输出,筛选OutputKey == "HelloWorldApi"的项得到 API Gateway URL,最后用requests.get请求它并断言返回{"message": "hello world"}

查看函数日志与清理资源

SAM CLI 提供sam logs命令,可直接从命令行拉取已部署 Lambda 的日志并支持实时跟踪。该命令对所有AWS Lambda 函数都适用,不限于通过 SAM 部署的函数:

sam-app$ sam logs -n HelloWorldFunction --stack-name sam-app --tail

-n指定函数名(此处对应模板中的HelloWorldFunction),--stack-name指定所属栈(默认栈名为sam-app),--tail表示持续跟踪新日志,便于在排障时快速定位问题。

实验结束后清理本次创建的样例应用,使用 AWS CLI 删除对应 CloudFormation 栈(假设沿用项目名作为栈名):

aws cloudformation delete-stack --stack-name sam-app

如需在现有模板上追加资源,直接在 template.yaml 中补充资源声明即可。模板采用 SAM 语法简化了函数、触发器与 API 等常见无服务器资源的配置;SAM 规范之外的资源可回退为标准 CloudFormation 资源类型,且通过同样的部署流程随应用代码一起更新。

小结

spec/fixtures/sam-app 是一个结构完整、可独立部署的 AWS SAM Hello World 工程:template.yaml声明了 Lambda 函数与隐式 API Gateway 资源及输出,hello_world/app.py提供符合代理集成格式的处理函数,events/event.json与两层测试构成离线验证与线上验收闭环。在 Kong 仓库里,它更承担着不可替代的联调职责——作为sam local start-lambda的模板输入,为 spec/03-plugins/27-aws-lambda/08-sam-integration_spec.lua 提供本地模拟的HelloWorldFunction,从而在不触达真实 AWS 的前提下验证 Kong AWS Lambda 插件从“接收请求 → 签名调用函数 → 代理返回响应”的完整链路,并以201状态码验证了代理集成模式的结果透传行为。理解了这一 fixture,你既掌握了一套可复用的无服务器应用本地开发流程,也看清了网关类项目如何借助它做插件级联调验证。

【免费下载链接】kong🦍 The API and AI Gateway项目地址: https://gitcode.com/GitHub_Trending/ko/kong

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询