Rumah > pembangunan bahagian belakang > Golang > Cara mencipta jenis generik untuk middleware lambda dalam go

Cara mencipta jenis generik untuk middleware lambda dalam go

WBOY
Lepaskan: 2024-02-06 09:35:11
ke hadapan
546 orang telah melayarinya

如何在 go 中为 lambda 中间件创建泛型类型

Kandungan soalan

Saya menggunakan go in aws lambda dan mencari penyelesaian perisian tengah biasa. Saya mempunyai kod berikut:

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))
Salin selepas log masuk

Fungsi middleware mempunyai parameter events.apigatewaywebsocketproxyrequest 因为目标处理程序 wshandler menggunakan jenis ini.

Saya mempunyai pengendali lain yang mengambil parameter event events.apigatewayproxyrequest seperti yang ditunjukkan di bawah. Perisian tengah ini tidak boleh digunakan kerana parameter tidak sepadan.

graphqlquerymutationhandler(ctx context.context, event events.apigatewayproxyrequest){
...
}
Salin selepas log masuk

Saya cuba menukar pemegang perisian tengah kepada interface{} tetapi ia tidak berjaya. pergi mengadu tentang jenis ini.

type HandlerFunc func(context.Context, interface{}) (interface{}, error)
Salin selepas log masuk

Adakah terdapat cara untuk menjadikan perisian tengah berfungsi untuk mana-mana jenis pengendali?


Jawapan Betul


Izinkan saya berkongsi penyelesaian yang berkesan yang dapat saya tiru pada sistem saya. Pertama, izinkan saya berkongsi dengan anda susun atur projek yang saya gunakan:

events/
  http_event.json
  sqs_event.json
hello-world/
  main.go
sqs/
  main.go
middlewares/
  middlewares.go
Salin selepas log masuk

Sekarang, mari fokus pada kod.

middlewares/middlewares.go

Kod adalah seperti berikut:

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)
    })
}
Salin selepas log masuk

Mari kita ringkaskan konsep asas:

  • Kami menentukan pembungkus untuk struktur event 结构体,它将成为我们的通用事件。它是 record.
  • record 结构使用结构嵌入来嵌入我们要处理的所有事件(例如 event.apigatewayproxyrequestsqsevent).
  • Kami bergantung pada ini dalam tandatangan perisian tengah untuk menjadi segenerik yang mungkin.

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"
            }
        }
    ]
}
Salin selepas log masuk

Tiada apa yang boleh dikatakan di sini.

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"
                }
            ]
        }
    ]
}
Salin selepas log masuk

Perkara yang sama berlaku di sini.

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))
}
Salin selepas log masuk

Sila ambil perhatian bagaimana kami mendapatkan maklumat acara.

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))
}
Salin selepas log masuk

Akhir

Ada beberapa perkara yang perlu dipertimbangkan:

  1. Sebelum mengikuti penyelesaian ini, saya cuba menggunakan parameter jenis tanpa berjaya. Mereka nampaknya tidak dibenarkan dalam tandatangan middleware.
  2. Kod terlalu dipermudahkan dan belum siap pengeluaran.

Jika ini membantu atau anda memerlukan apa-apa lagi, sila beritahu saya, terima kasih!

Atas ialah kandungan terperinci Cara mencipta jenis generik untuk middleware lambda dalam go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan