我正在 aws lambda 中使用 go 並尋找通用的中間件解決方案。我有以下程式碼:
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))
中間件函數有一個參數 events.apigatewaywebsocketproxyrequest
因為目標處理程序 wshandler
使用此類型。
我有另一個處理程序,它採用參數 event events.apigatewayproxyrequest
,如下所示。由於參數不匹配,因此無法使用此中間件。
graphqlquerymutationhandler(ctx context.context, event events.apigatewayproxyrequest){ ... }
我嘗試將中間件句柄更改為 interface{}
,但不起作用。 go 抱怨這種類型。
type HandlerFunc func(context.Context, interface{}) (interface{}, error)
有沒有辦法讓中間件適用於任何處理程序類型?
讓我分享我能夠在我的系統上複製的工作解決方案。首先跟大家分享我使用的專案佈局:
events/ http_event.json sqs_event.json hello-world/ main.go sqs/ main.go middlewares/ middlewares.go
現在,讓我們專注於程式碼。
middlewares/middlewares.go
#程式碼如下:
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) }) }
讓我們總結一下基本概念:
event
結構體,它將成為我們的通用事件。它是 record
結構的包裝器。 record
結構體使用結構嵌入來嵌入我們要處理的所有事件(例如 event.apigatewayproxyrequest
和 sqsevent
)。 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" } } ] }
這裡沒什麼好說的。
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" } ] } ] }
這也適用於這裡。
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)) }
請注意我們如何取得活動資訊。
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)) }
有幾個注意事項要考慮:
如果這有幫助或您需要其他任何東西,請告訴我,謝謝!
以上是如何在 go 中為 lambda 中間件建立泛型類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!