package main import ( "context" "encoding/json" "fmt" "log" "net/http" "os" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" "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" ) // Reading represents a single IoT measurement item returned to clients type Reading struct { DeviceID string `json:"deviceId" dynamodbav:"deviceId"` Timestamp string `json:"timestamp" dynamodbav:"timestamp"` Temperature float64 `json:"temperature" dynamodbav:"temperature"` Humidity float64 `json:"humidity" dynamodbav:"humidity"` } type ResponseBody struct { Data []Reading `json:"data"` } func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { tableName := os.Getenv("TABLE_NAME") if tableName == "" { log.Print("TABLE_NAME environment variable not set") return events.APIGatewayV2HTTPResponse{StatusCode: http.StatusInternalServerError}, nil } cfg, err := config.LoadDefaultConfig(ctx) if err != nil { log.Printf("failed to load AWS config: %v", err) return events.APIGatewayV2HTTPResponse{StatusCode: http.StatusInternalServerError}, nil } db := dynamodb.NewFromConfig(cfg) // Simple Scan as requested for the initial version scanInput := &dynamodb.ScanInput{ TableName: &tableName, } scanOutput, err := db.Scan(ctx, scanInput) if err != nil { log.Printf("dynamodb scan error: %v", err) return events.APIGatewayV2HTTPResponse{StatusCode: http.StatusInternalServerError}, nil } readings := make([]Reading, 0, len(scanOutput.Items)) for _, item := range scanOutput.Items { var r Reading err := attributevalue.UnmarshalMap(item, &r) if err != nil { // skip items that fail to unmarshal but log them log.Printf("failed to unmarshal item: %v", err) continue } readings = append(readings, r) } body := ResponseBody{Data: readings} b, err := json.Marshal(body) if err != nil { log.Printf("failed to marshal response: %v", err) return events.APIGatewayV2HTTPResponse{StatusCode: http.StatusInternalServerError}, nil } return events.APIGatewayV2HTTPResponse{ StatusCode: http.StatusOK, Headers: map[string]string{ "Content-Type": "application/json", }, Body: string(b), }, nil } func main() { lambda.Start(handler) }