禁用Lambda代理集成后,如何通过API Gateway向异步Lambda传参?
问题背景与描述
我们有一个AWS Lambda函数,功能是调用OpenAI API,根据传入的transcript生成博客风格的page_content,之后更新DynamoDB表中对应的Page条目。Lambda函数代码如下:
import boto3 import json import openai def lambda_handler(event, context): dynamodb = boto3.client('dynamodb') openai.api_key = "XXXXX" d = json.loads(event['body']) pageId = d['page_id'] transcript = d['transcript'] conversation = [ {"role": "system", "content": "Assistant"}, {"role": "user", "content": transcript}, {"role": "system", "content":"Provide a blog post for the content above."} ] response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=conversation, temperature=1, max_tokens=2000, top_p=1, frequency_penalty=0, presence_penalty=0 ) page_content = response['choices'][0]['message']['content'] state = "COMPLETE" response = dynamodb.update_item( TableName='Pagedb-XXXXXX-dev', Key={'id': {'S': pageId}}, UpdateExpression='SET content = :val1, contentState = :val2', ExpressionAttributeValues={ ':val1': {'S': page_content}, ':val2': {'S': state} }, ) return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS,POST,GET' } }
该函数通过API Gateway由React应用调用,前端代码如下:
const response = await axios.post( 'https://XXXX.execute-api.us-east-2.amazonaws.com/default/generate-content', {page_id: page.id, transcript: page.transcript}, );
核心问题:大部分调用会触发API Gateway的30秒超时报错,但Lambda函数本身仍能执行完成。为解决超时问题,我们禁用了「Use Lambda Proxy Integration」,并添加了值为Event的HTTP Header X-Amz-Invocation-Type实现异步调用。但禁用代理集成后,无法再像之前那样通过Lambda的event参数获取前端传递的数据。
已实现的解决方案
通过在API Gateway的集成请求中配置映射模板,成功实现了参数传递,操作步骤如下:
- 进入API Gateway的集成请求 -> 映射模板,将「请求体传递」设置为「未定义模板时」
- 点击「添加映射模板」,输入
application/json - 选择「生成模板:方法请求传递」,然后修改为以下内容:
#set($allParams = $input.params()) { "method" : "$context.httpMethod", ## API方法 "authcontext" : "$context.authorizer.stringkey", ## Lambda授权器的可选输出 ## 透传请求体 "body" : $input.json('$'), ## 透传请求头、查询字符串和路径参数 "params" : { #foreach($type in $allParams.keySet()) #set($params = $allParams.get($type)) "$type" : { #foreach($paramName in $params.keySet()) "$paramName" : "$util.escapeJavaScript($params.get($paramName))" #if($foreach.hasNext),#end #end } #if($foreach.hasNext),#end #end } }
- 更新Lambda函数的参数获取逻辑,直接从
event['body']中读取数据:
pageId = event['body']['page_id'] transcript = event['body']['transcript']
内容的提问来源于stack exchange,提问作者Adam Ryason
相关产品推荐
相关产品推荐

