AWS Gateway代理集成Lambda时Query String参数传递失败原因排查
问题:API Gateway代理集成Lambda时,查询参数传递失败?
背景
我想用AWS API Gateway作为调用第三方潮汐API的管控渠道,目前有一个Lambda函数,可接收Event JSON并从外部API获取数据。Lambda的axios模块通过zip包上传。
Lambda函数代码
const axios = require('axios'); exports.handler = async (event) => { const url = 'https://api.marea.ooo/v2/tides'; const options = { method: 'GET', params: { latitude: event.latitude, longitude: event.longitude }, headers: { 'x-marea-api-token': API_KEY }, }; const response = await axios.get(url, options) return { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*" }, "body": JSON.stringify(response.data), }; }
Lambda控制台测试用Event JSON
{ "latitude": 53, "longitude": 78 }
Lambda控制台测试正常,参数能正确传递给第三方API并返回结果。
问题现象
将Lambda与API Gateway的代理集成关联后,在Gateway测试页面传入查询字符串latitude=53&longitude=78进行GET请求时,出现Axios错误。我已在方法请求中配置了latitude和longitude作为URL查询字符串参数,但只有在Lambda里硬编码经纬度参数时,Gateway测试才能成功获取第三方API响应:
params: { latitude: 36, longitude: 78 }
试过用event.queryStringParameters.latitude和直接event.latitude两种方式,都没效果,请问问题出在哪?
问题原因及解决方案
核心原因
API Gateway代理集成的事件结构和Lambda控制台测试的自定义Event完全不同:
- Lambda控制台测试用的是自定义扁平结构Event,所以
event.latitude能直接取到值 - API Gateway代理集成传入Lambda的是标准代理事件格式,查询参数嵌套在
queryStringParameters对象里,且默认是字符串类型,第三方API可能需要数字类型参数
修复步骤
- 从
event.queryStringParameters中正确读取参数,同时做空值校验避免报错 - 将字符串类型的经纬度转为数字,匹配第三方API的参数类型要求
- 增加异常捕获,方便排查请求失败的具体原因
修改后的Lambda代码:
const axios = require('axios'); exports.handler = async (event) => { try { // 从代理事件中获取查询参数,做空值校验 const { latitude, longitude } = event.queryStringParameters || {}; if (!latitude || !longitude) { return { statusCode: 400, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*" }, body: JSON.stringify({ error: '缺少必填参数latitude或longitude' }) }; } const url = 'https://api.marea.ooo/v2/tides'; const options = { method: 'GET', params: { latitude: Number(latitude), // 转换为数字类型 longitude: Number(longitude) }, headers: { 'x-marea-api-token': process.env.API_KEY // 建议用环境变量存储密钥,不要硬编码 }, }; const response = await axios.get(url, options); return { statusCode: 200, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*" }, body: JSON.stringify(response.data), }; } catch (error) { // 捕获异常并返回详细信息,辅助排查 return { statusCode: 500, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*" }, body: JSON.stringify({ error: '请求第三方API失败', details: error.message, requestParams: event.queryStringParameters }) }; } }
额外建议
- 不要将API_KEY硬编码在代码中,存储到Lambda的环境变量中,通过
process.env.API_KEY读取,提升安全性 - 在API Gateway中配置请求参数校验规则,提前拦截缺少参数的请求,减少Lambda的无效调用
内容的提问来源于stack exchange,提问作者jpa317
相关产品推荐
相关产品推荐

