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?
3 Réponses :
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?
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}
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 ;-)