Go语言Lambda函数通过API Gateway返回嵌套JSON遇转义问题求助
问题原因
你遇到的问题根源在于:data是一段JSON格式的字符串,直接赋值给RequestBody.Data后,json.Marshal会将其视为普通字符串处理,自动添加转义字符来保留字符串的原始格式,最终导致data字段输出为带转义的字符串,而非预期的嵌套JSON对象。
解决方案
需要先将JSON字符串解析为Go的结构化类型(结构体或map),再赋值给Data字段,这样json.Marshal处理时会将其序列化为嵌套的JSON对象,而非转义字符串。
方法1:使用结构体(推荐,类型安全)
定义与data结构匹配的Go结构体,将JSON字符串解析为该结构体实例:
package main import ( "encoding/json" "log" "net/http" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) type Response struct { StatusCode int `json:"statusCode"` Headers map[string]string `json:"headers"` Body string `json:"body"` } type RequestBody struct { Data User `json:"data"` Message string `json:"message"` } // 定义data对应的结构体 type User struct { Username string `json:"username"` Age int `json:"Age"` } const ( data string = ` { "username":"Random User", "Age":20 }` ) func EventHandler(request events.APIGatewayProxyRequest) (Response, error) { response := Response{} log.Println(request.Headers) // 解析JSON字符串为User结构体 var user User if err := json.Unmarshal([]byte(data), &user); err != nil { log.Println("解析data失败:", err) return Response{StatusCode: http.StatusInternalServerError}, err } body := RequestBody{Data: user, Message: "This is sample"} b, err := json.Marshal(body) if err != nil { log.Println("序列化body失败:", err) return Response{StatusCode: http.StatusInternalServerError}, err } response.Body = string(b) response.StatusCode = http.StatusOK // 添加响应头,确保返回正确的JSON格式 response.Headers = map[string]string{"Content-Type": "application/json"} log.Println("Before Return") return response, nil } func main() { lambda.Start(EventHandler) }
方法2:使用map(灵活,适合结构不固定的场景)
如果不想定义结构体,可以用map[string]any来解析JSON字符串:
package main import ( "encoding/json" "log" "net/http" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) type Response struct { StatusCode int `json:"statusCode"` Headers map[string]string `json:"headers"` Body string `json:"body"` } type RequestBody struct { Data map[string]any `json:"data"` Message string `json:"message"` } const ( data string = ` { "username":"Random User", "Age":20 }` ) func EventHandler(request events.APIGatewayProxyRequest) (Response, error) { response := Response{} log.Println(request.Headers) // 解析JSON字符串为map var dataMap map[string]any if err := json.Unmarshal([]byte(data), &dataMap); err != nil { log.Println("解析data失败:", err) return Response{StatusCode: http.StatusInternalServerError}, err } body := RequestBody{Data: dataMap, Message: "This is sample"} b, err := json.Marshal(body) if err != nil { log.Println("序列化body失败:", err) return Response{StatusCode: http.StatusInternalServerError}, err } response.Body = string(b) response.StatusCode = http.StatusOK response.Headers = map[string]string{"Content-Type": "application/json"} log.Println("Before Return") return response, nil } func main() { lambda.Start(EventHandler) }
关键修改说明
- 不再直接将字符串
data赋值给RequestBody.Data,而是通过json.Unmarshal将其解析为Go的结构化类型。 - 解析后的类型在
json.Marshal时会被序列化为嵌套的JSON对象,而非转义字符串。 - 添加了错误处理逻辑,避免生产环境中因解析/序列化失败导致的静默错误。
- 新增
Content-Type响应头,确保API Gateway返回符合标准的JSON格式。
内容的提问来源于stack exchange,提问作者Abhishek
相关产品推荐
相关产品推荐

