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

Cara mencipta jenis generik untuk middleware lambda dalam go

WBOY
WBOYke hadapan
2024-02-06 09:35:11481semak imbas

如何在 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))

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){
...
}

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)

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

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)
    })
}

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"
            }
        }
    ]
}

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"
                }
            ]
        }
    ]
}

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))
}

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))
}

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam