3. API Gateway构建RESTful API
在 Serverless 架构中,API Gateway 是客户端与后端计算之间的“门面”。它把 HTTP 请求翻译成 Lambda 调用,同时承担路由、鉴权、校验、限流和版本发布等职责。本节围绕一条真实的 RESTful API 展开:一个“订单查询服务”,包含 GET /orders(列表)与 GET /orders/{id}(详情)两个资源路径,后端由 Lambda 处理。我们将依次说明资源与方法定义、阶段与部署、请求验证与转换、限流与 API 密钥,以及与 Lambda 的集成方式。
资源与方法:REST API 的骨架
API Gateway 的 REST API 采用“资源树 + 方法”的模型。资源(Resource)对应 URL 路径,方法(Method)对应 HTTP 动词。创建时先建根资源 /,再逐级创建子资源。例如先建 /orders,再在其下建路径参数资源 /{id},其中花括号表示占位符,实际请求 /orders/1001 时,id 会被解析为路径参数。
每个资源上挂载方法。以 GET /orders/{id} 为例,需要定义:方法请求(Method Request)——声明入参、授权方式;集成请求(Integration Request)——声明如何把请求转发给 Lambda;集成响应(Integration Response)——把 Lambda 返回映射为 HTTP 响应;方法响应(Method Response)——声明状态码与响应头。这四层结构是 REST API 的核心,理解它才能正确配置转换与校验。
路径参数需要在方法请求中显式声明。例如在 GET /orders/{id} 的方法请求里添加名为 id 的路径参数,并可在请求验证器中约束其格式。若未声明,集成模板中引用 $input.params('id') 将取不到值。
阶段与部署:让 API 可访问
API 定义完成后并不会自动对外生效,必须“部署”到某个阶段(Stage)。阶段是 API 的独立快照,拥有自己的 URL、变量和限流配置。常见做法是建立 dev、test、prod 三个阶段,分别指向不同后端或使用不同参数。
部署后得到调用地址,形如:
https://{api-id}.execute-api.{region}.amazonaws.com/{stage}/orders/1001
阶段变量(Stage Variables)用于在不同阶段切换后端,例如把 Lambda 别名设为 ${stageVariables.lambdaAlias},在 dev 阶段填 dev、prod 阶段填 prod,从而让同一份 API 定义指向不同版本的 Lambda。此外,还可以启用阶段缓存、设置日志级别与访问日志,便于排障。
请求验证与转换
请求验证器(Request Validator)可以在请求到达 Lambda 之前拦截非法请求,减少无效调用。它支持校验必填参数、查询字符串和请求体模型。例如为 GET /orders 定义查询参数 status(可选)与 limit(必填,整数),并创建 JSON Schema 模型约束请求体。若客户端缺少 limit,API Gateway 直接返回 400,不会触发 Lambda。
转换则通过映射模板(Mapping Template)完成。集成请求使用 Velocity 模板语言(VTL),把 HTTP 请求重塑为 Lambda 期望的事件结构。例如把路径参数与查询参数组装成 JSON:
{
"orderId": "$input.params('id')",
"status": "$input.params('status')",
"limit": $input.params('limit')
}
集成响应同样可用模板把 Lambda 的返回映射为指定状态码与响应体。例如 Lambda 返回 {"code":404,"message":"not found"},可通过正则匹配 code 映射为 HTTP 404。这样后端逻辑与 HTTP 语义解耦,前端拿到的始终是规范的 REST 响应。
限流与 API 密钥
限流(Throttling)保护后端不被突发流量击垮。API Gateway 提供账户级与阶段级限流,核心参数是速率(rate,每秒请求数)与突发(burst,令牌桶容量)。例如设置 rate=100、burst=200,表示稳态每秒 100 个请求,允许短时突增到 200。方法级还可单独覆盖,例如对写操作设置更严格的限流。
API 密钥(API Key)用于识别调用方并配合使用计划(Usage Plan)实施配额。使用计划可绑定阶段与方法,设置每日/每周配额和限流。密钥本身不是强鉴权手段,应与 IAM 授权、Lambda 授权方或 Cognito 结合使用。典型流程是:创建密钥 → 创建使用计划 → 关联阶段 → 把密钥分发给客户端,客户端在请求头 x-api-key 中携带。
与 Lambda 集成
集成类型选择 AWS_PROXY(Lambda 代理集成)最为常用:API Gateway 把完整请求(含路径、查询、头、体)作为事件传给 Lambda,Lambda 返回 statusCode、headers、body 三要素,API Gateway 原样转成 HTTP 响应。这种方式无需手写映射模板,灵活度高。若需要精细控制请求/响应格式,则使用非代理集成并配合映射模板。
Lambda 需要被授予 lambda:InvokeFunction 权限,通常由 API Gateway 自动创建资源策略完成。若使用阶段变量指向别名,权限需覆盖对应别名。下面是一个代理集成的 Lambda 处理示例(Node.js):
exports.handler = async (event) => {
const id = event.pathParameters?.id;
if (!id) {
return { statusCode: 400, body: JSON.stringify({ message: 'missing id' }) };
}
const order = await getOrder(id); // 假设的查询函数
if (!order) {
return { statusCode: 404, body: JSON.stringify({ message: 'not found' }) };
}
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(order)
};
};
部署后可用 curl 验证:curl -H "x-api-key: xxx" https://.../prod/orders/1001。若返回 403 且提示 Forbidden,通常是密钥缺失或使用计划未关联;若返回 502,多为 Lambda 返回格式不符合代理集成要求,需检查 statusCode 是否为数字、body 是否为字符串。
把上述环节串起来看:资源与方法定义 API 的“形状”,阶段与部署让它“上线”,验证与转换保证“输入规范、输出标准”,限流与密钥控制“谁能调、调多快”,Lambda 集成则提供“业务逻辑”。五者协同,才构成一条可运维、可扩展的 RESTful API。实际项目中建议先用代理集成快速打通链路,再按需引入验证器、映射模板和使用计划,避免一开始就过度配置。