0
votes

Comment capturer des événements AWS AppSync dans des sources de données lambda sans serveur

J'utilise une source de données lambda sans serveur pour une API AppSync

J'ai essayé le code suivant dans ma fonction lambda

package main

import (
    "context"
    "github.com/aws/aws-lambda-go/lambda"
    "log"
)


func main() {
    lambda.Start(Handler)
}

// Handler is your serverless lambda function
func Handler(ctx context.Context, event interface{}) error {
    log.Println(ctx)
    log.Println(event)
    return nil
}

Lorsque j'ai fait une requête à l'API, le contexte a été correctement consigné, mais l'événement a été enregistré en tant que { []}

J'ai essayé de changer le code lambda pour utiliser un événement qui est une interface vide

package main

import (
    "context"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "log"
)

func main() {
    lambda.Start(Handler)
}
// Handler is your serverless lambda function
func Handler(ctx context.Context, event events.AppSyncResolverTemplate) error {
    log.Println(ctx)
    log.Println(event)
    return nil
}

En interrogeant l'API maintenant, je peux voir qu'il y a une carte dans la map[field:getPerson arguments:map[personId:1]] journaux map[field:getPerson arguments:map[personId:1]]

Ma question est de savoir quel est le type valide à utiliser dans la signature du gestionnaire pour capturer l'événement AppSync?


0 commentaires

3 Réponses :


0
votes

Je ne crois pas que le events.AppSyncResolverTemplate soit la valeur appropriée qui devrait exister dans un objet d'événements passé à la source de données.

Je me trompe peut-être, mais je crois que ce que vous voyez dans les journaux où les événements sont imprimés est votre context.info qui montre votre requête et les arguments que vous passez.

query {
  getPerson(personId: "1")
}

Cela peut être utilisé pour diverses raisons au sein du lambda.

Pouvez-vous fournir plus d'informations sur ce que vous entendez par l'événement AppSync que vous souhaitez capturer?

Qu'espérez-vous voir dans cet événement?


0 commentaires

0
votes

J'ai résolu ce problème maintenant.

Il s'avère que la forme des données transmises à une source de données lambda sans serveur est définie par l'utilisateur.

Dans le SamTemplate, j'ai regardé le résolveur pour cette requête et il ressemblait à

package main

import (
    "context"
    "log"

    "github.com/aws/aws-lambda-go/lambda"
)

type GetPerson struct {
    PersonID string `json:"personId"`
}

func main() {
    lambda.Start(Handler)
}

// Handler is your serverless lambda function
func Handler(ctx context.Context, event GetPerson) error {
    log.Println(ctx)
    log.Println(event)

    return nil
}

J'ai changé ce résolveur en

getPersonQueryResolver:
    Type: "AWS::AppSync::Resolver"
    Properties:
      ApiId: !GetAtt accountApi.ApiId
      TypeName: "Query"
      FieldName: "getPerson"
      DataSourceName: !GetAtt PersonDatasource.Name
      RequestMappingTemplate: |
        {
          "version" : "2017-02-28",
          "operation": "Invoke",
          "payload": $utils.toJson($context.args)
        }
      ResponseMappingTemplate: |
        $utils.toJson($context.result)

puis j'ai changé le code lambda en

 getPersonQueryResolver:
    Type: "AWS::AppSync::Resolver"
    Properties:
      ApiId: !GetAtt accountApi.ApiId
      TypeName: "Query"
      FieldName: "getPerson"
      DataSourceName: !GetAtt PersonDatasource.Name
      RequestMappingTemplate: |
        {
          "version" : "2017-02-28",
          "operation": "Invoke",
          "payload": {
              "field": "getPerson",
              "arguments":  $utils.toJson($context.args)
          }
        }
      ResponseMappingTemplate: |
        $utils.toJson($context.result)

Cela a réussi à rassembler l'événement et à le consigner en tant que {1}


0 commentaires

0
votes

Si vous utilisez le nouveau résolveur Direct Lambda introduit en août 2020 ( https://aws.amazon.com/blogs/mobile/appsync-direct-lambda/ ), il n'y a aucun moyen de trouver le type d'événement sur Appsync dans le actuel Golang AWS SDK jusqu'à aujourd'hui.

Ils n'ont que AppSyncResolverTemplate, AppSyncIAMIdentity & AppSyncCognitoIdentity struct ( https://github.com/aws/aws-lambda-go/blob/v1.16.0/events/appsync.go ) donc vous devez décoder vous-même la demande entrante si vous y allez pour utiliser un résolveur lambda direct.

La raison pour laquelle ils ne l'ont pas fait jusqu'à présent est que jusqu'à présent, vous pouviez concevoir votre propre schéma à l'aide du Template Resolver (dans appsync), mais maintenant que la fonctionnalité Direct Lambda est sortie, je pense qu'ils doivent créer un nouveau type d'événement AppSync pour cela.

Jusque-là, je partage avec vous le code que j'ai écrit en extrayant tout l'événement morceau par morceau à cet effet dans l'espoir de gagner du temps pour la prochaine personne qui se trouvera dans ma situation.

*** Vous remarquerez qu'il n'y a pas de gestion des erreurs ici, juste le code nécessaire pour décoder AWS Event provenant d'AppSync ;-)

package main

import (
    "fmt"
    "context"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-lambda-go/lambdacontext"
    "log"
    "encoding/json"
    "bytes"
)

type Event struct {
    Arguments               map[string]string `json:"arguments"`
    Identity                string `json:"identity"`
    Info struct {
        FieldName           string `json:"fieldName"`
        ParentTypeName      string `json:"parentTypeName"`
        SelectionSetGraphQL string `json:"selectionSetGraphQL"`
        SelectionSetList    []string `json:"selectionSetList"`
        Variables           map[string]string `json:"variables"`
    }
    Prev                    string `json:"prev"`
    Request struct { 
        Headers struct {
            Accept                      string `json:"accept"`
            AcceptEncoding              string `json:"accept-encoding"`
            AcceptLanguage              string `json:"accept-language"`
            CloudfrontForwardedProto    string `json:"cloudfront-forwarded-proto"`
            CloudfrontIsDesktopViewer   string `json:"cloudfront-is-desktop-viewer"`
            CloudfrontIsMobileViewer    string `json:"cloudfront-is-mobile-viewer"`
            CloudfrontIsSmarttvViewer   string `json:"cloudfront-is-smarttv-viewer"`
            CloudfrontViewerCountry     string `json:"cloudfront-viewer-country"`
            CloudfrontIsTabletViewer    string `json:"cloudfront-is-tablet-viewer"`
            ContentLength               string `json:"content-length"`
            ContentType                 string `json:"content-type"`
            Host                        string `json:"host"`
            Hrigin                      string `json:"origin"`
            Referer                     string `json:"Referer"`
            SecFetchDest                string `json:"sec-fetch-dest"`
            SecFetchMode                string `json:"sec-fetch-mode"`
            SecFetchSite                string `json:"sec-fetch-site"`
            UserAgent                   string `json:"user-agent"`
            Via                         string `json:"via"`
            XAmzCfID                    string `json:"x-amz-cf-id"`
            XAmzUserAgent               string `json:"x-amz-user-agent"`
            XAmznTraceID                string `json:"x-amzn-trace-id"`
            XApiKey                     string `json:"x-api-key"`
            XForwardedFor               string `json:"x-forwarded-for"`
            XForwardedPort              string `json:"x-forwarded-port"`
            XForwardedProto             string `json:"x-forwarded-proto"`
        }
    }
    Source              string `json:"source"`
    Stash               map[string]string `json:"stash"`
}


func main() {
    lambda.Start(HandleLambdaEvent)
}

func HandleLambdaEvent(ctx context.Context, event interface{}) error {

    fmt.Printf("---------------{LAMBDA ctx Start}---------------\n")
    // Event context
    lc, _ := lambdacontext.FromContext(ctx)
    //fmt.Println("Context:",ctx)
    fmt.Println("AwsRequestID:",lc.AwsRequestID)
    fmt.Println("Identity:",lc.Identity)
    fmt.Println("InvokedFunctionArn:",lc.InvokedFunctionArn)
    fmt.Println("ClientContext:",lc.ClientContext)
    fmt.Println("ClientContext.Client:",lc.ClientContext.Client)
    fmt.Println("CognitoIdentityID:",lc.Identity.CognitoIdentityID)
    fmt.Println("CognitoIdentityPoolID:",lc.Identity.CognitoIdentityPoolID)
    deadline, _ := ctx.Deadline()
    fmt.Println("ContextDeadline:",deadline)


    fmt.Printf("---------------{LAMBDA AWS Event Start}---------------\n")
    log.Println(event)


    fmt.Printf("---------------{Marshal Event Start}---------------\n")
    //eventJsonm, _ := json.Marshal(event)
    eventJsonm, _ := json.MarshalIndent(event, "", "    ")
    log.Printf("EVENT Marsal: %s", eventJsonm)
    

    fmt.Printf("---------------{Decode Start}---------------\n")
    var Event Event
    r := bytes.NewReader([]byte(eventJsonm))
    json.NewDecoder(r).Decode(&Event)
    fmt.Println("Arguments:",Event.Arguments)
    fmt.Println("Identity:",Event.Identity)
    fmt.Println("Info.FieldName:",Event.Info.FieldName)
    fmt.Println("Info.ParentTypeName:",Event.Info.ParentTypeName)
    fmt.Println("Info.SelectionSetGraphQL:",Event.Info.SelectionSetGraphQL)
    fmt.Println("Info.SelectionSetList:",Event.Info.SelectionSetList)
    fmt.Println("Info.Variables:",Event.Info.Variables)
    fmt.Println("Prev:",Event.Prev)
    // fmt.Println("Event.Request.Headers:",Event.Request.Headers)
    // fmt.Println("Event.Request.Headers.Accept:",Event.Request.Headers.Accept)
    // fmt.Println("Event.Request.Headers.AcceptEncoding:",Event.Request.Headers.AcceptEncoding)
    // fmt.Println("Event.Request.Headers.AcceptLanguage:",Event.Request.Headers.AcceptLanguage)
    // ...

    fmt.Println("Source:",Event.Source)
    fmt.Println("Stash:",Event.Stash)

    
    return nil
}

Prendre plaisir ;-)


0 commentaires