Open yosriady opened 6 years ago
You can try to receive interface{}
or json.RawMessage
instead of event struct.
Then you need manually detect which event it is and marshal it to proper event
@jkaflik could you maybe give an example of how that would work with an interface{}
? Right now my handler looks like this:
func handler(event interface{}) error {
sesEvent, ok := event.(sesevt.Event)
if ok {
...
}
_, ok = event.(cloudwatchschedevt.Event)
if ok {
...
}
return fmt.Errorf("Event type not recognized: %+v", event)
}
When SES sends an event it is not recognized, any idea why? It looks like the data is already unmarshalled (a print of the event reveals a structure with maps and data) so the type assertion is probably wrong...
Fixed it with the mapstructure library. map[string]interface{}
as handler argument and do basic checking on the top-level fields, then decode with the library to the appropriate struct. Seems like a bit of a hack but the initial json unmarshall in the Lambda Go library is hidden from us and unavoidable right now.
Creating a lambda for each event seems cleaner (if you need to access event datas that is), otherwise you run the risk of cluttered handlers that a difficult to reason about.
https://code.tutsplus.com/tutorials/solid-part-1-the-single-responsibility-principle--net-36074
I encounter this scenario, I have to handle S3 event direct from S3 or relay by SNS. In Python code, I can simply check the payload keys like this.
But I don't know how to do the same thing in Golang's way.
@soloradish if you have an example of each payload it would be easier to provide an example of how to tackle. What I've done in the past is this:
lambda.StartHandler
and passed it a struct that implements Invoke(ctx context.Context, event []byte) ([]byte, error)
. Now I have access to the raw event payload.Invoke
I marshal event
into two different structs. In my case this was an API Gateway proxy request and a dynamodbevent request.Does anyone have a complete example of how to unmarshel that I can extrapolate from ?
Does anyone have a complete example of how to unmarshel that I can extrapolate from ?
What have you tried? Which different event types do you need to disambiguate?
Created a Golang library to simplify demuxing multiple event types.
How about like this:
func main() {
lambda.Start(handler)
}
// handler argument type is `map[string]interface{}`
func handler(ctx context.Context, event map[string]interface{}) (interface{}, error) {
jsonEvent, err := json.Marshal(event)
if err != nil {
return nil, err
}
// apigateway's event includes `httpMethod` field.
if _, ok := event["httpMethod"]; ok {
var agwEvent events.APIGatewayProxyRequest
if err := json.Unmarshal(jsonEvent, &agwEvent); err != nil {
return nil, err
}
return agwEvent, nil
}
// sqs's event includes `Records` field.
if _, ok := event["Records"]; ok {
var sqsEvent events.SQSEvent
if err := json.Unmarshal(jsonEvent, &sqsEvent); err != nil {
return nil, err
}
return sqsEvent, nil
}
return nil, errors.New("unsupported event type")
}
Do you have an example of how the handler code might look like for a function that can be triggered by more than one event?
For example, let's say we have a function that can be triggered by both API Gateway and DynamoDB events.