如何让Chalice Lambda绕过API网关与授权器直接相互调用?
解决方案:Lambda直接调用绕过API Gateway
嘿,这事儿好办!既然不想走API Gateway和Cognito授权器,那咱们就直接让Lambda1通过AWS的SDK调用Lambda2,完全跳过网关层,开销能降不少。下面是具体的实现步骤和代码示例:
1. 给Lambda1配置调用权限
首先得确保Lambda1的执行角色有权限调用Lambda2。如果是用Chalice部署的,直接修改.chalice/policy.json文件,添加Lambda调用权限:
{ "Version": "2012-10-17", "Statement": [ // 保留你原来的其他权限 { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:你的AWS区域:你的AWS账号ID:function:你的Lambda2函数全名" } ] }
你可以在AWS Lambda控制台找到Lambda2的ARN,直接填进去就行。
2. 在Lambda1里编写调用代码
接下来修改Lambda1的say_hello函数,用boto3直接调用Lambda2,然后解析返回结果。注意Chalice返回的响应会被包装成标准Lambda格式,所以解析的时候要留意:
import boto3 import json from chalice import Chalice, Response app = Chalice(app_name='lambda1') @app.route('/hello') def say_hello(): # 初始化Lambda客户端 lambda_client = boto3.client('lambda') try: # 调用Lambda2,替换成你实际的Lambda2函数名 invoke_response = lambda_client.invoke( FunctionName='lambda2-dev-a_name', # Chalice部署的函数名格式一般是「app名-环境-函数名」 InvocationType='RequestResponse', # 同步调用,等待结果返回 Payload=json.dumps({}) # 如果Lambda2需要参数,在这里传递,这里不需要就传空对象 ) # 解析返回的Payload内容 response_payload = json.loads(invoke_response['Payload'].read()) # Chalice的路由返回会被包装成带body的结构,所以取body里的name name = response_payload['body']['name'] return Response({'message': f'hello {name}'}) except Exception as e: # 增加异常处理,避免调用失败直接导致接口崩溃 return Response({'error': f'Failed to call Lambda2: {str(e)}'}, status_code=500)
3. 几个关键注意点
- 函数名别写错:Chalice部署的Lambda函数名格式是
appName-stage-functionName,比如你的Lambda2 app叫lambda2,部署在dev环境,函数名就是lambda2-dev-a_name,去Lambda控制台确认一下准没错。 - 同步调用适合你的场景:这里用的
RequestResponse是同步调用,会等待Lambda2执行完返回结果,刚好符合你要获取name的需求;如果是不需要等待的场景,可以用Event异步调用,但咱们这里用同步就对了。 - 异常处理很重要:一定要加try-except块,不然如果Lambda2不存在、权限不够或者执行出错,整个
/hello接口就直接返回500错误了,加了处理能返回更友好的错误信息。
这样改完之后,Lambda1调用Lambda2就完全绕开了API Gateway和Cognito授权器,直接在Lambda服务之间通信,开销会小很多,也不用再走授权流程啦。
内容的提问来源于stack exchange,提问作者cahen
相关产品推荐
相关产品推荐

