在GO Lambda中处理DynamoDB项目



我正在执行一个简单的表扫描,以从DynamoDB表products中获取所有项目。这是整个Lambda:

package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
type Product struct {
productUUID string
name        string
description string
brand       string
price       string
category    string
dateAdded   string
}
func handleRequest() (string, error) {
cfg, err := config.LoadDefaultConfig(context.TODO(), func(o *config.LoadOptions) error {
o.Region = "us-east-2"
return nil
})
if err != nil {
panic(err)
}
svc := dynamodb.NewFromConfig(cfg)
out, err := svc.Scan(context.TODO(), &dynamodb.ScanInput{
TableName: aws.String("products"),
})
if err != nil {
panic(err)
}
for _, item := range out.Items {
fmt.Println(item)
}
return "Items", nil // Temporary debugging return (always 200). I'd like to return a json object here
}
func main() {
lambda.Start(handleRequest)
}

当我取回数据时,我可以以以下形式打印出每个项目:

map[brand:0xc0002f38a8 category:0xc0002f3848 dateAdded:0xc0002f3830 name:0xc0002f3800 price:0xc0002f37a0 productUUID:0xc0002f3818]

如何将这些Items转换为我在上面定义的结构,然后返回lambda所期望的json响应(基本上是HTTP响应代码和json形式的Items(?

扫描表返回项的映射,并且您希望将映射转换为结构,因此为了将映射列表转换为要使用attributevalue的结构。aws-sdk-go-v2下的UnmarshalListOfMaps。在以前的版本中,它在generandattribute中,但他们决定更改v2中的包。

products := []Product{}
err = attributevalue.UnmarshalListOfMaps(out.Items, &products)
if err != nil {
panic(fmt.Sprintf("failed to unmarshal Dynamodb Scan Items, %v", err))
}
productsJson, err := json.Marshal(products)
if err != nil {
panic(err)
}

我在Product结构中看到的一个问题是,您需要使用导出的名称,还需要为结构字段定义json标记,否则数据将不会被分解为结构。因此,为了将表中的扫描项返回到json响应中,您的代码应该是这样的。


package main
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
type Product struct {
ProductUUID string `json:"productUUID"`
Name        string `json:"name"`
Description string `json:"description"`
Brand       string `json:"brand"`
Price       string `json:"price"`
Category    string `json:"category"`
DateAdded   string `json:"dateAdded"`
}
func handleRequest() (events.APIGatewayProxyResponse, error) {
products := []Product{}
cfg, err := config.LoadDefaultConfig(context.TODO(), func(o *config.LoadOptions) error {
o.Region = "us-east-2"
return nil
})
if err != nil {
panic(err)
}
svc := dynamodb.NewFromConfig(cfg)
out, err := svc.Scan(context.TODO(), &dynamodb.ScanInput{
TableName: aws.String("products"),
})
if err != nil {
panic(err)
}
err = attributevalue.UnmarshalListOfMaps(out.Items, &products)
if err != nil {
panic(fmt.Sprintf("failed to unmarshal Dynamodb Scan Items, %v", err))
}
productsJson, err := json.Marshal(products)
if err != nil {
panic(err)
}
resp := events.APIGatewayProxyResponse{
StatusCode:      200,
IsBase64Encoded: false,
Body:            string(productsJson),
Headers: map[string]string{
"Content-Type": "application/json",
},
}
return resp, nil
}
func main() {
lambda.Start(handleRequest)
}

p.S:扫描整个发电机表并将其作为响应返回是非常昂贵的,您应该避免它。

最新更新