How to create a generic type for lambda middleware in go
I am using go with aws lambda and looking for a general middleware solution. I have the following code:
func wshandler(ctx context.context, event events.apigatewaywebsocketproxyrequest) (events.apigatewayproxyresponse, error) { } type handlerfunc func(context.context, events.apigatewaywebsocketproxyrequest) (events.apigatewayproxyresponse, error) func logmiddleware(next handlerfunc) handlerfunc { return handlerfunc(func(ctx context.context, event events.apigatewaywebsocketproxyrequest) (events.apigatewayproxyresponse, error) { return next(ctx, event) }) } lambda.start(logmiddleware(wshandler))
The middleware function has a parameter events.apigatewaywebsocketproxyrequest
because the target handler wshandler
uses this type.
I have another handler that takes the parameter event events.apigatewayproxyrequest
as shown below. This middleware cannot be used because the parameters do not match.
graphqlquerymutationhandler(ctx context.context, event events.apigatewayproxyrequest){ ... }
I tried changing the middleware handle to interface{}
but it didn't work. go complains about this type.
type HandlerFunc func(context.Context, interface{}) (interface{}, error)
Is there a way to make the middleware work for any handler type?
Correct Answer
Let me share a working solution that I was able to replicate on my system. First, let me share with you the project layout I use:
events/ http_event.json sqs_event.json hello-world/ main.go sqs/ main.go middlewares/ middlewares.go
Now, let’s focus on the code.
middlewares/middlewares.go
code show as below:
package middlewares import ( "context" "fmt" "github.com/aws/aws-lambda-go/events" ) type record struct { events.apigatewayproxyrequest `json:",omitempty"` events.sqsevent `json:",omitempty"` } type event struct { records []record `json:"records"` } type handlerfunc func(ctx context.context, event event) (string, error) func logmiddleware(ctx context.context, next handlerfunc) handlerfunc { return handlerfunc(func(ctx context.context, event event) (string, error) { fmt.println("log from middleware!") return next(ctx, event) }) }
Let’s summarize the basic concepts:
- We define the
event
structure, which will become our general event. It is a wrapper around therecord
structure.
The record
structure uses structure embedding to embed all the events we want to handle (such asevent.apigatewayproxyrequest
andsqsevent
).- We rely on this in the middleware signature to be as general as possible.
events/http_event.json
{ "records": [ { "body": "{\"message\": \"hello world\"}", "resource": "/hello", "path": "/hello", "httpmethod": "get", "isbase64encoded": false, "querystringparameters": { "foo": "bar" }, "pathparameters": { "proxy": "/path/to/resource" }, "stagevariables": { "baz": "qux" }, "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "accept-encoding": "gzip, deflate, sdch", "accept-language": "en-us,en;q=0.8", "cache-control": "max-age=0", "cloudfront-forwarded-proto": "https", "cloudfront-is-desktop-viewer": "true", "cloudfront-is-mobile-viewer": "false", "cloudfront-is-smarttv-viewer": "false", "cloudfront-is-tablet-viewer": "false", "cloudfront-viewer-country": "us", "host": "1234567890.execute-api.us-east-1.amazonaws.com", "upgrade-insecure-requests": "1", "user-agent": "custom user agent string", "via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (cloudfront)", "x-amz-cf-id": "cdehvqoznx43vyqb9j2-nvch-9z396uhbp027y2jvkcpnlmgjhqlaa==", "x-forwarded-for": "127.0.0.1, 127.0.0.2", "x-forwarded-port": "443", "x-forwarded-proto": "https" }, "requestcontext": { "accountid": "123456789012", "resourceid": "123456", "stage": "prod", "requestid": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "requesttime": "09/apr/2015:12:34:56 +0000", "requesttimeepoch": 1428582896000, "identity": { "cognitoidentitypoolid": null, "accountid": null, "cognitoidentityid": null, "caller": null, "accesskey": null, "sourceip": "127.0.0.1", "cognitoauthenticationtype": null, "cognitoauthenticationprovider": null, "userarn": null, "useragent": "custom user agent string", "user": null }, "path": "/prod/hello", "resourcepath": "/hello", "httpmethod": "get", "apiid": "1234567890", "protocol": "http/1.1" } } ] }
Nothing to say here.
events/sqs_event.json
{ "records": [ { "records": [ { "messageid": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receipthandle": "messagereceipthandle", "body": "my own event payload!", "attributes": { "approximatereceivecount": "1", "senttimestamp": "1523232000000", "senderid": "123456789012", "approximatefirstreceivetimestamp": "1523232000001" }, "messageattributes": {}, "md5ofbody": "4d1d0024b51659ad8c3725f9ba7e2471", "eventsource": "aws:sqs", "eventsourcearn": "arn:aws:sqs:us-east-1:123456789012:myqueue", "awsregion": "us-east-1" } ] } ] }
The same applies here.
hello-world/main.go
package main import ( "context" "fmt" "httplambda/middlewares" "github.com/aws/aws-lambda-go/lambda" ) func lambdahandler(ctx context.context, event middlewares.event) (string, error) { _ = ctx fmt.println("path:", event.records[0].apigatewayproxyrequest.path) fmt.println("hi from http-triggered lambda!") return "", nil } func main() { // start the lambda handler lambda.start(middlewares.logmiddleware(context.background(), lambdahandler)) }
Please note how we obtain event information.
sqs/main.go
package main import ( "context" "fmt" "httplambda/middlewares" "github.com/aws/aws-lambda-go/lambda" ) func lambdaHandler(ctx context.Context, event middlewares.Event) (string, error) { _ = ctx fmt.Println("Queue name:", event.Records[0].SQSEvent.Records[0].EventSourceARN) fmt.Println("Hi from SQS-triggered lambda!") return "", nil } func main() { lambda.Start(middlewares.LogMiddleware(context.Background(), lambdaHandler)) }
finals
There are several considerations to consider:
- Before following this solution, I tried using type parameters without success. They don't seem to be allowed in the middleware's signature.
- The code is oversimplified and not production ready.
If this helps or you need anything else, please let me know, thank you!
The above is the detailed content of How to create a generic type for lambda middleware in go. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



OpenSSL, as an open source library widely used in secure communications, provides encryption algorithms, keys and certificate management functions. However, there are some known security vulnerabilities in its historical version, some of which are extremely harmful. This article will focus on common vulnerabilities and response measures for OpenSSL in Debian systems. DebianOpenSSL known vulnerabilities: OpenSSL has experienced several serious vulnerabilities, such as: Heart Bleeding Vulnerability (CVE-2014-0160): This vulnerability affects OpenSSL 1.0.1 to 1.0.1f and 1.0.2 to 1.0.2 beta versions. An attacker can use this vulnerability to unauthorized read sensitive information on the server, including encryption keys, etc.

The article explains how to use the pprof tool for analyzing Go performance, including enabling profiling, collecting data, and identifying common bottlenecks like CPU and memory issues.Character count: 159

The article discusses writing unit tests in Go, covering best practices, mocking techniques, and tools for efficient test management.

The library used for floating-point number operation in Go language introduces how to ensure the accuracy is...

Queue threading problem in Go crawler Colly explores the problem of using the Colly crawler library in Go language, developers often encounter problems with threads and request queues. �...

Backend learning path: The exploration journey from front-end to back-end As a back-end beginner who transforms from front-end development, you already have the foundation of nodejs,...

The article discusses the go fmt command in Go programming, which formats code to adhere to official style guidelines. It highlights the importance of go fmt for maintaining code consistency, readability, and reducing style debates. Best practices fo

Under the BeegoORM framework, how to specify the database associated with the model? Many Beego projects require multiple databases to be operated simultaneously. When using Beego...
