tec*_*oke 6 amazon-web-services aws-lambda aws-api-gateway
So, turns out I had it all along but I was logging it out incorrectly. I had been doing a Object.keys(event).forEach and console logging each key and value. I guess this didn't display the value as it's a nested object. Using JSON.stringify, as per @robC3's answer shows all the nested objects and values properly and is easier too! TL;DR just use curly braces in your gateway paths and they will be present in event.pathParameters.whateverYouCalledThem
I'm used to express land where you just write /stuff/:things in your route and then req.params.things becomes available in your handler for 'stuff'.
I'm struggling to get the same basic functionality in CDK. I have a RestAPI called 'api' and resources like so...
const api = new apigateway.RestApi(this, "image-cache-api", { //options })
const stuff = api.root.addResource("stuff")
const stuffWithId = get.addResource("{id}")
stuffWithId.addMethod("GET", new apigateway.LambdaIntegration(stuffLambda, options))
Run Code Online (Sandbox Code Playgroud)
Then I deploy the function and call it at https://<api path>/stuff/1234
Then in my lambda I check event.pathParameters and it is this: {id: undefined}
I've had a look through the event object and the only place I can see 1234 is in the path /stuff/1234 and while I could just parse it out of that I'm sure that's not how it's supposed to work.
:/
Most of the things I have turned up while googling mention "mapping templates". That seems overly complicated for such a common use case so I had been working to the assumption there would be some sort of default mapping. Now I'm starting to think there isn't. Do I really have to specify a mapping template just to get access to path params and, if so, where should it go in my CDK stack code?
I tried the following...
stuffWithId.addMethod("GET", new apigateway.LambdaIntegration(stuffLambda, {
requestTemplate: {
"id": "$input.params('id')",
}
}))
Run Code Online (Sandbox Code Playgroud)
But got the error...
error TS2559: Type '{ requestTemplate: { id: string; }; }' has no properties in common with type 'LambdaIntegrationOptions'.
Run Code Online (Sandbox Code Playgroud)
I'm pretty confused as to whether I need requestTemplate, requestParametes, or something else entirely as all the examples I have found so far are for the console rather than CDK.
rob*_*b3c 11
这工作得很好,当您在浏览器中测试它时,您可以看到完整路径、路径参数、查询参数等在事件结构中的位置。
// lambdas/handler.ts
// This code uses @types/aws-lambda for typescript convenience.
// Build first, and then deploy the .js handler.
import { APIGatewayProxyHandler, APIGatewayProxyResult } from 'aws-lambda';
export const main: APIGatewayProxyHandler = async (event, context, callback) => {
return <APIGatewayProxyResult> {
body: JSON.stringify([ event, context ], null, 4),
statusCode: 200,
};
}
Run Code Online (Sandbox Code Playgroud)
// apig-lambda-proxy-demo-stack.ts
import * as path from 'path';
import { aws_apigateway, aws_lambda, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class ApigLambdaProxyDemoStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const stuffLambda = new aws_lambda.Function(this, 'stuff-lambda', {
code: aws_lambda.Code.fromAsset(path.join('dist', 'lambdas')),
handler: 'handler.main',
runtime: aws_lambda.Runtime.NODEJS_14_X,
});
const api = new aws_apigateway.RestApi(this, 'image-cache-api');
const stuff = api.root.addResource('stuff');
const stuffWithId = stuff.addResource('{id}');
stuffWithId.addMethod('GET', new aws_apigateway.LambdaIntegration(stuffLambda));
}
}
Run Code Online (Sandbox Code Playgroud)
此示例查询:
https://[id].execute-api.[region].amazonaws.com/prod/stuff/1234?q1=foo&q2=bar
给出了这个回应(摘录):
如果您想在 API 中的某个点处理任意路径,您将需要探索IResource.addProxy()CDK 方法。例如,
api.root.addProxy({
defaultIntegration: new aws_apigateway.LambdaIntegration(stuffLambda),
});
Run Code Online (Sandbox Code Playgroud)
这会{proxy+}在示例中的 API 根处创建一个资源,并将所有请求转发给 lambda。您可以在同一个处理程序中处理所有端点,而不是在 API Gateway 中配置每个端点。
首先要注意的是,所有使用 LambdaIntegration 模块的 cdk 实际上都必须是 Post - Get 方法,当您将数据发送到 Lambda 时,LambdaIntegration 的 Get 方法不起作用。如果你想专门进行 get 操作,你必须在 api 中为其编写自定义方法。
现在,我只用 Python 完成了这个,但希望你能明白这个想法:
my_rest_api = apigateway.RestApi(
self, "MyAPI",
retain_deployments=True,
deploy_options=apigateway.StageOptions(
logging_level=apigateway.MethodLoggingLevel.INFO,
stage_name="Dev
)
)
a_resource = apigateway.Resource(
self, "MyResource",
parent=my_rest_api.root,
path_part="Stuff"
)
my_method = apigateway.Method(
self, "MyMethod",
http_method="POST",
resource=quoting_resource,
integration=apigateway.AwsIntegration(
service="lambda",
integration_http_method="POST",
path="my:function:arn"
)
)
Run Code Online (Sandbox Code Playgroud)
你的资源构造定义了你的路径 - 如果你想在每个级别都有方法,你可以将多个资源链接在一起,或者只是将它们全部放在path_part中 - 这样你就可以定义resourceA,并将其用作resourceB中的父级 - 这将让您的resourceAPathPart/resourceBPathPart/访问您的lambda。
或者你可以将它们全部放在resourceA中,path_part = stuff/path/ect
我在这里使用 AwsIntegration 方法而不是 LambdaIntegration,因为在完整代码中,我使用阶段变量根据我所处的阶段动态选择不同的 lambda,但效果相当相似
| 归档时间: |
|
| 查看次数: |
7874 次 |
| 最近记录: |