I don't know if you found the solution yet but i have found solution.
Here it is..
package main
import (
"errors"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func main() {
lambda.Start(Handler)
}
type Event1 struct {
//Event Attributes
}
type Event2 struct {
//Event Attributes
}
type Composite struct {
*Event1
*Event2
*events.S3Event
}
func Handler(c Composite) error {
if c.Event1 != nil {
//go along with code based on Event1
} else if c.Event2 != nil {
//go along with code based on Event2
} else if c.S3Event != nil {
//go along with code based on S3Event
} else {
return errors.New("wrong event type")
}
return nil
}
This will work fine as you can see whichever event is fired that struct will not be empty and also you can easily add extra events by adding their pointer in Composite
struct just like i have added *Event1
and *Event2
.
There is one drawback that you can not Put SQSEvent and S3Event togather as their attributes have same name and json tag Record
Also if to event have same attributes that will also backfire as it will put zero value
in all attributes which are same in different struct
Also there is one more solution which can overcome above problems
package main
import (
"encoding/json"
"errors"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func main() {
lambda.Start(Handler)
}
type CustomEvent struct {
//Give EventSource "aws:manual" value to determine event is manual
EventSource string `json:"eventSource"`
//Other CustomEvent Attributes
}
func Handler(event map[string]interface{}) error {
//marshal map to get json of data
eventMarshaled, err := json.Marshal(event)
if err != nil {
return err
}
//Flag for determining if any one of the event is parsed
var eventParsed bool
//declare CustomEvent variable to use while Unmarshaling
var c CustomEvent
if err := json.Unmarshal(eventMarshaled, &c); err == nil {
if c.EventSource == "aws:manual" {
eventParsed = true
//your code based on CustomEvent
}
return nil
}
if !eventParsed {
//declare SQSEvent variable to use while Unmarshaling
var sqsEvent events.SQSEvent
if err := json.Unmarshal(eventMarshaled, &sqsEvent); err == nil {
for _, message := range sqsEvent.Records {
if message.EventSource == "aws:sqs" {
eventParsed = true
//Your Code based on sqs event
}
}
return nil
}
}
if !eventParsed {
//declare S3Event variable to use while Unmarshaling
var s3Event events.S3Event
if err := json.Unmarshal(eventMarshaled, &s3Event); err == nil {
for _, message := range s3Event.Records {
if message.EventSource == "aws:sqs" {
eventParsed = true
//Your Code based on s3 event
}
}
return nil
}
}
return errors.New("wrong event type")
}
As you can see the handler gets map[string]interface{}
by default from aws sdk you just need to marshal it and then unmarshal it to your desired type.you have to give eventSource
attributes to all your custom events and check their eventSource
so that you can do your operations based on that.
also don't forget to send that eventSource
whenever you are sending manual event other then aws specific like SQS,SNS,S3 etc... and you can see in above example how to check eventSource
for SQS and S3 you can find eventSource
attribute in mostly every Events aws provides but i am not sure but you can easily find some unique attributes in every aws provided Events which can be checked for nil
and you can then determine which type of event it is.
this method fixes the problem in first solution but it also adds unnecessary marshaling and unmarshaling of json and also there is different methods of checking different events
but i think there is no sureshot way to do this