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

如何在Go语言AWS Lambda中直接接收API Gateway原始请求字节

问题:Go语言Lambda无法直接接收API Gateway原始请求体字节

我尝试用Go语言结合AWS Lambda与API Gateway构建REST API,希望直接处理原始请求体字节,无需手动进行Base64转换。目前API Gateway已配置application/octet-stream为Binary Media Types,Lambda集成设置了ContentHandling.CONVERT_TO_BINARY,但Lambda始终返回JSON解析错误,提示无法将二进制数据解析为JSON。

当前配置与错误信息

CDK集成代码

const testPath = api.root.addResource('test');
const testIntegration = new LambdaIntegration(props.testFunc, {
    proxy: false,
    contentHandling: ContentHandling.CONVERT_TO_BINARY,
    passthroughBehavior: PassthroughBehavior.WHEN_NO_MATCH,
});
testPath.addMethod('POST', testIntegration);

Go Lambda处理函数

func Handler(ctx context.Context, payload []byte) ([]byte, error) {
    fmt.Println("received...")
    fmt.Printf("received request of length: %v", len(payload))
    return nil, nil
}

func main() {
    lambda.Start(Handler)
}

错误响应

{"message": "Could not parse request body into json: Could not parse payload into json: Invalid UTF-8 start byte 0xa3\n at [Source: (byte[])"\uFFFDWQo\uFFFD8\u0010.......\uFFFD"[truncated 360 bytes]; line: 1, column: 6]"}

API Gateway日志摘要

(xxx) Method request body before transformations: [Binary Data]
(xxx) Endpoint request body after transformations: [Binary Data]
(xxx) Execution failed: Could not parse request body into json: Could not parse payload into json: Invalid UTF-8 start byte 0xa3

问题原因

Lambda的Go运行时要求输入参数必须是可被encoding/json反序列化的类型:

  • 当你使用[]byte作为处理函数参数时,运行时期望输入是base64编码的JSON字符串,然后自动解码为字节数组。
  • 但当前API Gateway直接传递原始二进制数据给Lambda,运行时尝试将非JSON格式的二进制数据解析为JSON,导致报错。

解决方案

方案1:自动处理Base64转换(代码无需手动解码)

调整API Gateway配置,将原始二进制数据Base64编码后以JSON字符串形式传递给Lambda,让Go运行时自动解码为字节数组。

修改后的CDK代码

const testPath = api.root.addResource('test');
const testIntegration = new LambdaIntegration(props.testFunc, {
    proxy: false,
    contentHandling: ContentHandling.CONVERT_TO_TEXT,
    passthroughBehavior: PassthroughBehavior.WHEN_NO_MATCH,
});
testPath.addMethod('POST', testIntegration, {
    // 映射模板:将原始请求体Base64编码后作为JSON字符串传递
    requestTemplates: {
        'application/octet-stream': '$util.base64Encode($input.body)',
    },
});

保持原Go处理函数不变

func Handler(ctx context.Context, payload []byte) ([]byte, error) {
    fmt.Println("received...")
    fmt.Printf("received request of length: %v", len(payload))
    // 直接使用payload原始字节处理业务逻辑
    return nil, nil
}

func main() {
    lambda.Start(Handler)
}

方案2:使用API Gateway代理模式+V2请求事件

如果希望完全避免Base64转换的感知,可以使用API Gateway V2的HTTP API代理模式,结合APIGatewayV2HTTPRequest事件类型,此时请求体将直接以原始字节对应的字符串形式传递(无需手动解码)。

修改后的CDK代码

const testPath = api.root.addResource('test');
const testIntegration = new LambdaIntegration(props.testFunc, {
    proxy: true, // 启用代理模式
    contentHandling: ContentHandling.CONVERT_TO_BINARY,
    passthroughBehavior: PassthroughBehavior.WHEN_NO_MATCH,
});
testPath.addMethod('POST', testIntegration);

修改后的Go处理函数

import (
    "context"
    "fmt"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)

func Handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) ([]byte, error) {
    // req.Body即为原始请求体字节对应的字符串,直接转换为[]byte使用
    requestBytes := []byte(req.Body)
    fmt.Printf("received request of length: %v", len(requestBytes))
    return nil, nil
}

func main() {
    lambda.Start(Handler)
}

内容的提问来源于stack exchange,提问作者Swati

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:15:55