amazon-web-services - 找不到 Golang 的 API 网关映射模板
问题描述
我在 AWS API Gateway 上为 Twilio 创建了一个 webhook,它以application/x-www-form-urlencoded
Content-Type 发送请求。我无法为 Golang 编写或找到映射模板。我正在关注此文档 -用于创建 API 网关的链接。我目前正在使用文档中使用的以下模板 -
我正在使用的 API Gateway 映射模板:
#set($httpPost = $input.path('$').split("&"))
{
#foreach( $kvPair in $httpPost )
#set($kvTokenised = $kvPair.split("="))
#if( $kvTokenised.size() > 1 )
"$kvTokenised[0]" : "$kvTokenised[1]"#if( $foreach.hasNext ),#end
#else
"$kvTokenised[0]" : ""#if( $foreach.hasNext ),#end
#end
#end
}
API Gateway 映射模板创建的 JSON:
{
"ToCountry": "US",
"ToState": "UT",
"SmsMessageSid": "SMed65aaxxxxxx5c7938df",
"NumMedia": "0",
"ToCity": "",
"FromZip": "",
"SmsSid": "SMed65aaxxxxxx938df",
"FromState": "",
"SmsStatus": "received",
"FromCity": "",
"Body": "Testing+again",
"FromCountry": "IN",
"To": "%2B1xxxxxx848",
"ToZip": "",
"NumSegments": "1",
"MessageSid": "SMed65aa5dxxxx7938df",
"AccountSid": "AC23xxxd98",
"From": "%2B9xxxxxx90",
"ApiVersion": "2010-04-01"
}
Lambda 代码(Golang)
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
fmt.Printf("%+v\n", request)
fmt.Println("request Body:", request.Body)
fmt.Println("request HTTPMethod:", request.HTTPMethod)
fmt.Println("request Headers:", request.Headers)
fmt.Println("request:", request.RequestContext.RequestID)
}
API 网关日志
(442f74ed-39e5-4372-bf85-42bf814f802f) Extended Request Id: EIaYxxMF3lQ=
(442f74ed-39e5-4372-bf85-42bf814f802f) Method request path: {}
(442f74ed-39e5-4372-bf85-42bf814f802f) Method request query string: {}
(442f74ed-39e5-4372-bf85-42bf814f802f) Method request headers: {Accept=*/*, Cache-Control=max-age=259200, X-Twilio-Signature=ZWg2v7xxxfnBlPyxE=, User-Agent=TwilioProxy/1.1, X-Forwarded-Proto=https, I-Twilio-Idempotency-Token=e5d1xxx221bc4, X-Forwarded-For=54.xxxx.227, Host=xxxxxxx.execute-api.us-east-1.amazonaws.com, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=1-5de67103-7994dbxxx0dbd872, Content-Type=application/x-www-form-urlencoded}}
(442f74ed-39e5-4372-bf85-42bf814f802f) Method request body before transformations: ToCountry=US&ToState=UT&SmsMessageSid=SMed65axxx595c7938df&NumMedia=0&ToCity=&FromZip=&SmsSid=SMed65aa5xxccdd595c7938df&FromState=&SmsStatus=received&FromCity=&Body=Good+Day&FromCountry=IN&To=%2Bxxxx848&ToZip=&NumSegments=1&MessageSid=SMed65axxxd595c7938df&AccountSid=AC23a2cbxxx65a66d98&From=%2B9xxxx5590&ApiVersion=2010-04-01
(442f74ed-39e5-4372-bf85-42bf814f802f) Endpoint request URI: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:6xxxxxxxx6:function:Twillio_connector_test/invocations
(442f74ed-39e5-4372-bf85-42bf814f802f) Endpoint request headers: {x-amzn-lambda-integration-tag=442f74ed-39e5-4372-bf85-42bf814f802f, Authorization=*****27aa7a, X-Amz-Date=20191203T142819Z, x-amzn-apigateway-api-id=xxxxx, X-Amz-Source-Arn=arn:aws:execute-api:us-east-1:69xxxx886:xxxxxxx/v1/POST/message, Accept=application/x-www-form-urlencoded, User-Agent=AmazonAPIGateway_f7504e7yc6, X-Amz-Security-Token=IQoJbxxxhQH [TRUNCATED]
(442f74ed-39e5-4372-bf85-42bf814f802f) Endpoint request body after transformations:
{
"ToCountry": "US",
"ToState": "UT",
"SmsMessageSid": "SMed65aaxxxxxx5c7938df",
"NumMedia": "0",
"ToCity": "",
"FromZip": "",
"SmsSid": "SMed65aaxxxxxx938df",
"FromState": "",
"SmsStatus": "received",
"FromCity": "",
"Body": "Good+Day",
"FromCountry": "IN",
"To": "%2B1xxxxxx848",
"ToZip": "",
"NumSegments": "1",
"MessageSid": "SMed65aa5dxxxx7938df",
"AccountSid": "AC23xxxd98",
"From": "%2B9xxxxxx90",
"ApiVersion": "2010-04-01"
}
(442f74ed-39e5-4372-bf85-42bf814f802f) Endpoint response headers: {Date=Tue, 03 Dec 2019 14:28:20 GMT, Content-Type=application/json, Content-Length=43, Connection=keep-alive, x-amzn-RequestId=168394b7-c152-4434-af02-03a03b6f3090, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-5de67103-7994dbxxxxbe30dbd872;sampled=0}
(442f74ed-39e5-4372-bf85-42bf814f802f) Endpoint response body before transformations: "Lambda function is completed successfully"
(442f74ed-39e5-4372-bf85-42bf814f802f) Method response body after transformations: Lambda function is completed successfully
(442f74ed-39e5-4372-bf85-42bf814f802f) Method response headers: {X-Amzn-Trace-Id=Root=1-5de67103-7994dbxxxxxxd872;Sampled=0, Content-Type=application/xml}
Lambda 函数日志
request: { map[] map[] map[] map[] map[] map[] { { } map[] } Good Day false}
{Resource: Path: HTTPMethod: Headers:map[] MultiValueHeaders:map[] QueryStringParameters:map[] MultiValueQueryStringParameters:map[] PathParameters:map[] StageVariables:map[] RequestContext:{AccountID: ResourceID: Stage: RequestID: Identity:{CognitoIdentityPoolID: AccountID: CognitoIdentityID: Caller: APIKey: AccessKey: SourceIP: CognitoAuthenticationType: CognitoAuthenticationProvider: UserArn: UserAgent: User:} ResourcePath: Authorizer:map[] HTTPMethod: APIID:} Body:Good Day IsBase64Encoded:false}
request Body: Good Day
request HTTPMethod:
request Headers: map[]
在 Lambda 日志中,我可以看到只有创建的 JSON 主体被映射到events.APIGatewayProxyRequest
,而不是其他参数。原因是映射模板创建的JSON不是以下格式 -
The events.APIGatewayProxyRequest parameter in golang:
// APIGatewayProxyRequest contains data coming from the API Gateway proxy
type APIGatewayProxyRequest struct {
Resource string `json:"resource"` // The resource path defined in API Gateway
Path string `json:"path"` // The url path for the caller
HTTPMethod string `json:"httpMethod"`
Headers map[string]string `json:"headers"`
MultiValueHeaders map[string][]string `json:"multiValueHeaders"`
QueryStringParameters map[string]string `json:"queryStringParameters"`
MultiValueQueryStringParameters map[string][]string `json:"multiValueQueryStringParameters"`
PathParameters map[string]string `json:"pathParameters"`
StageVariables map[string]string `json:"stageVariables"`
RequestContext APIGatewayProxyRequestContext `json:"requestContext"`
Body string `json:"body"`
IsBase64Encoded bool `json:"isBase64Encoded,omitempty"`
}
如果有人能指出我的相关文件,我将不胜感激。欢迎提出建议。
解决方案
看起来您可能正在尝试使用代理集成处理程序签名来处理特定资源上的 Lambda 自定义集成事件。我不相信在代理集成的情况下映射模板是相关的。
Lambda 集成
使用 Lambda 响应 API Gateway 请求有两种主要方式。第一种是使用Lambda 集成。此方法通常涉及完全由您自行决定将请求转换为自定义 Lambda 事件。大部分繁重的工作由 API Gateway 完成。例如,您可以将查询参数仅转换为字符串,然后仅将该字符串提供给您的 Lambda 处理程序。
func handler(e string) (<something>, error) {}
或者,您可以从标头中获取一个值,从 URL 中获取一部分,然后构建一个 JSON 对象以提供给您的处理程序。
type event struct {
URLPart string `json:"url_part"`
QueryPart string `json:"query_part"`
}
func handler(e *event) (<something>, error) {}
要点
- 您完全控制到达您的功能的请求事件
- 您完全控制 Lambda 返回的响应
- API 网关完成了更多繁重的工作
代理集成
然后是代理集成。代理集成将发送到您在 API 网关中指定的资源(通常是 {proxy+} 资源上的 ANY 方法)的每个请求转换为事件模块中定义的events.APIGatewayProxyRequest结构类型。这消除了您将请求转换为您必须指定的特定事件的需要,并从 API Gateway 中删除了繁重的请求并将其放入您的 Lambda 处理程序中。
代理集成处理程序必须具有以下签名:
func handler(c context.Context, e events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {}
要点
- 请求和响应总是一样的,events.APIGatewayProxyRequest 和 events.APIGatewayProxyResponse
- API Gateway 中需要做的工作要少得多
- 通常在您已经对 Golang 解决方案进行了大量投资并且不想将其分解为 Lambda 集成的单个资源部分时使用。
这是一个链接,解释了更多的差异和一些注意事项。
推荐阅读
- hexo - hexo 博客 URL 末尾有“%20”
- python - 如何使用 python 子进程从标准输出获取输出?
- python - 未定义的行到列,按年和月分组
- bpmn - 这个 BPMN 中的错误是什么?
- python - 如何在mysql python中修复“TypeError:需要一个整数(获取类型IntVar)”
- javascript - 如何在草稿 js 编辑器中呈现提供的 HTML?
- django - 附加标头以在 Django 中重定向
- mysql - 如何为 MySQL 选择查询输出文件指定列名?
- python - 如何在 Python 中传递任意参数
- java - 在android中制作一个自定义函数,以便我可以在任何地方使用它