aws lambda in golang triggered by sqs and getting type errors

huangapple go评论93阅读模式
英文:

aws lambda in golang triggered by sqs and getting type errors

问题

我正在开发一个由API Gateway和SQS触发的Lambda函数。

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"

	regcode "company/gateway/lambda/regcode/lib"
)

func main() {

	// 使用SQS和Lambda URL处理程序启动Lambda函数
	lambda.Start(func(ctx context.Context, event interface{}) error {
		fmt.Println("事件类型:", event)
		switch event.(type) {
		case events.SQSEvent:
			return regcode.HandlerSqs(ctx, event.(events.SQSEvent))
		case events.APIGatewayProxyRequest:
			response, err := regcode.HandlerLambdaURL(ctx, event.(events.APIGatewayProxyRequest))
			if err != nil {
				log.Println(err)
				return err
			}
			log.Printf("API Gateway响应:%v", response)
			return nil
		default:
			return fmt.Errorf("未知的事件类型:%T", event)
		}
	})
}

但是我的switch语句无法识别我使用的是sqs还是apigateway事件。它总是进入默认语句。例如,对于SQS,我使用以下事件:

{
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "Hello from SQS!",
      "attributes": {
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1523232000000",
        "SenderId": "123456789012",
        "ApproximateFirstReceiveTimestamp": "1523232000001"
      },
      "messageAttributes": {},
      "md5OfBody": "{{{md5_of_body}}}",
      "md5OfMessageAttributes": "test",
      "eventSource": "aws:sqs",
      "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
      "awsRegion": "us-east-1"
    }
  ]
}

并且收到以下消息:

未知的事件类型:map[string]interface {}: errorString

你有什么想法我做错了什么?我刚开始使用golang,所以我在这里迷失了。

另外,我尝试直接将事件发送到regcode.HandlerSqs,但是我得到了一个类型转换错误。像这样:

func main() {

	// 使用SQS和Lambda URL处理程序启动Lambda函数
	lambda.Start(func(ctx context.Context, event interface{}) error {
		sqsEvent, _ := event.(SQSEvent)
		// ...
	})
}

sqsEvent是空的。

英文:

I'm developing a lambda that is triggered by API Gateway and SQS.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"

	regcode "company/gateway/lambda/regcode/lib"
)

func main() {

	// Start the Lambda function with both SQS and Lambda URL handlers
	lambda.Start(func(ctx context.Context, event interface{}) error {
		fmt.Println("Event type: ", event)
		switch event.(type) {
		case events.SQSEvent:
			return regcode.HandlerSqs(ctx, event.(events.SQSEvent))
		case events.APIGatewayProxyRequest:
			response, err := regcode.HandlerLambdaURL(ctx, event.(events.APIGatewayProxyRequest))
			if err != nil {
				log.Println(err)
				return err
			}
			log.Printf("API Gateway response: %v", response)
			return nil
		default:
			return fmt.Errorf("unknown event type: %T", event)
		}
	})
}

But my switch type is not able to identify when I use an sqs or apigateway event. It always falls in the default statement. For SQS for instance I'm using this event:

{
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "Hello from SQS!",
      "attributes": {
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1523232000000",
        "SenderId": "123456789012",
        "ApproximateFirstReceiveTimestamp": "1523232000001"
      },
      "messageAttributes": {},
      "md5OfBody": "{{{md5_of_body}}}",
      "md5OfMessageAttributes": "test",
      "eventSource": "aws:sqs",
      "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
      "awsRegion": "us-east-1"
    }
  ]
}

and getting this message:

unknown event type: map[string]interface {}: errorString

Any idea what I'm doing wrong? I'm new to using golang so I'm lost here.

Also, I tried to send the event directly to the regcode.HandlerSqs, but I got a type conversion error. Like this:

func main() {

	// Start the Lambda function with both SQS and Lambda URL handlers
	lambda.Start(func(ctx context.Context, event interface{}) error {
		sqsEvent, _ := event.(SQSEvent)
		// ...
	})
}

sqsEvent is empty.

答案1

得分: 2

你有什么想法,我做错了什么吗?

AWS Lambda处理程序将反映func参数的类型,并创建与您的签名匹配的event类型。

因此,如果您声明func的第二个参数为event events.SQSEvent,AWS将获取其类型events.SQSEvent,创建一个这样的对象,并将其传递进来。

同样,如果您要在func中使用event events.APIGatewayProxyRequest,AWS将反映event应该是events.APIGatewayProxyRequest,并创建该对象。

换句话说,AWS不会检查传入请求是来自SQS还是API。这仅基于您处理程序的签名来确定。因此,如果您在func中使用event interface{},AWS将创建您指定要创建的确切对象interface{},而不是其他任何类型。

这就是为什么您的switch语句不起作用的原因。最简单的解决方法是为SQS和API分别创建两个Lambda函数。

英文:

> Any idea what I'm doing wrong?

AWS lambda handler will reflect types of your arguments in func, and then will create event type matching your signature.

So if you declare your func to be have second argument as event events.SQSEvent, AWS will get its type, events.SQSEvent, creates such an object, and pass it in.

Same, if you are going to use event events.APIGatewayProxyRequest in func, aws will reflect that event should be events.APIGatewayProxyRequest and will create that.

In other words, AWS does not check whether the incoming request is from SQS or API. This is only determined based on your handler's signature. So if you use event interface{} in func, aws creates exactly what you specified to be created, interface{}, not any other type.

So that's why your switch does not work. The easiest way to fix that, would be to have two lambda functions, with for SQS and one for API.

huangapple
  • 本文由 发表于 2023年4月2日 11:10:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75909931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定