You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:42:39