使用AWS Lambda服务API调用会带来很多警告和限制,包括通过AWS API Gateway集成代理服务器的限制,其中一个是负载大小限制,另一个是负载编码困难,无论是二进制、文本或JSON,还是二进制-无论是二进制blob(字节)还是base64编码字符串。
jogvjijk1#
为了让文件往返于API网关-〉Lambda -〉S3和S3 -〉Lambda -〉API网关之间,您必须配置POSTMAN、API网关、Lambda、和本地代码来处理base64编码的有效负载。这是API Gateway转换二进制blob有效负载的一种方式。here有多种定义方式,但以下示例是最简单的:
步骤0 -配置
1.您将需要为您想要用来处理二进制文件的每个API网关启用二进制编码类型。1.导航至AWS控制台-〉API网关-〉选择您的API -〉设置-〉二进制媒体类型1.添加*/*1.单击“保存更改”或更新IAC以修改API网关。使用无服务器框架,您可以执行以下操作:serverless.yml
*/*
serverless.yml
provider: apiGateway: binaryMediaTypes: - '*/*'
第一步-透过POSTMAN上载
Headers.Content-Type
multipart/form-data; boundary=<calculated when request is sent>
Headers.Content-Length
<calculated when request is sent>
form-data
key
filename
file
value
步骤2 - 1上传Lambda处理程序功能
func UploadLambda(ctx context.Context, lambdaReq events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { if !lambdaReq.IsBase64Encoded { return ... } fileHeaders, err := GetHeaders(lambdaReq, MaxFileSizeBytes) if err != nil { return ... } if len(fileHeaders) != 1 { return ... } fileName := uuid.New().String() fileExtension := path.Ext(fileHeaders[0].Filename) fileName = fileName + fileExtension // take the first file uploaded via HTTP and upload it to S3 uploadResult, err := UploadHeader(fileHeaders[0], os.Getenv("REGION"), os.Getenv("BUCKET"), fileName) if err != nil { return... } return events.APIGatewayProxyResponse{Status: 200}, nil }
步骤2 - 2解析Lambda函数的标头
func GetHeaders(lambdaReq events.APIGatewayProxyRequest, maxFileSizeBytes int64) ([]*multipart.FileHeader, error) { // https://github.com/aws/aws-lambda-go/issues/117 headers := http.Header{} for header, values := range lambdaReq.Headers { headers.Add(header, values) } contentType := headers.Get("Content-Type") if contentType == "" { return... } _, params, err := mime.ParseMediaType(contentType) if err != nil { return... } boundary := params["boundary"] if boundary == "" { return... } stringReader := strings.NewReader(lambdaReq.Body) b64Reader := base64.NewDecoder(base64.StdEncoding, stringReader) multipartReader := multipart.NewReader(b64Reader, boundary) form, err := multipartReader.ReadForm(maxFileSizeBytes) if err != nil { return... } var files []*multipart.FileHeader for currentFileName := range form.File { files = append(files, form.File[currentFileName][0]) } return files, nil }
第2 - 3步上传到S3功能
func UploadHeader(fileHeader *multipart.FileHeader, region, bucket, name string) (*UploadRes, error) { file, err := fileHeader.Open() if err != nil { return... } var fileContents []byte _, err = file.Read(fileContents) if err != nil { return... } awsSession, err := session.NewSession(&aws.Config{ Region: aws.String(region)}, ) if err != nil { return... } uploader := s3manager.NewUploader(awsSession) uploadOutput, err := uploader.Upload(&s3manager.UploadInput{ Bucket: aws.String(bucket), Key: aws.String(name), Body: file, }) if err != nil { return... } return &UploadRes{ S3Path: filepath.Join(bucket, name), S3URL: uploadOutput.Location, }, nil }
步骤3 - 1下载Lambda处理程序函数
func DownloadLambda(ctx context.Context, lambdaReq events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { file := Get(...) fileBytes, err := Download(os.Getenv("REGION"), os.Getenv("BUCKET"), file.Name) if err != nil { return... } return FileB64Res(file.ContentType, nil, fileBytes) }
步骤3 - 2下载S3功能
func Download(region, bucket, name string) ([]byte, error) { awsSession, err := session.NewSession(&aws.Config{ Region: aws.String(region)}, ) if err != nil { return... } downloader := s3manager.NewDownloader(awsSession) var fileBytes []byte writeAtBuffer := aws.NewWriteAtBuffer(fileBytes) getObjectInput := &s3.GetObjectInput{ Bucket: aws.String(bucket), Key: aws.String(name), } // functional options pattern bytesDownloaded, err := downloader.Download(writeAtBuffer, getObjectInput, func(downloader *s3manager.Downloader) { downloader.Concurrency = 0 }) if err != nil { return... } if bytesDownloaded == 0 { return... } return writeAtBuffer.Bytes(), nil } func FileB64Res(contentType string, headers map[string]string, fileBytes []byte) (events.APIGatewayProxyResponse, error) { if headers == nil { headers = map[string]string{ ContentTypeKey: contentType, } } else { headers[ContentTypeKey] = contentType } return events.APIGatewayProxyResponse{ StatusCode: http.StatusOK, Headers: headers, Body: base64.StdEncoding.EncodeToString(fileBytes), IsBase64Encoded: true, }, nil }
步骤4 - 1透过 Postman 下载
Headers.Accept
1条答案
按热度按时间jogvjijk1#
为了让文件往返于API网关-〉Lambda -〉S3和S3 -〉Lambda -〉API网关之间,您必须配置POSTMAN、API网关、Lambda、和本地代码来处理base64编码的有效负载。这是API Gateway转换二进制blob有效负载的一种方式。here有多种定义方式,但以下示例是最简单的:
步骤0 -配置
1.您将需要为您想要用来处理二进制文件的每个API网关启用二进制编码类型。
1.导航至AWS控制台-〉API网关-〉选择您的API -〉设置-〉二进制媒体类型
1.添加
*/*
1.单击“保存更改”或更新IAC以修改API网关。使用无服务器框架,您可以执行以下操作:
serverless.yml
第一步-透过POSTMAN上载
Headers.Content-Type
应为multipart/form-data; boundary=<calculated when request is sent>
Headers.Content-Length
应为<calculated when request is sent>
1.在Body下选择
form-data
,在key
下输入filename
,输入file
,value
作为选择的二进制文件上传。PDF是一个很好的工作示例。步骤2 - 1上传Lambda处理程序功能
步骤2 - 2解析Lambda函数的标头
第2 - 3步上传到S3功能
步骤3 - 1下载Lambda处理程序函数
步骤3 - 2下载S3功能
步骤4 - 1透过 Postman 下载
1.将
Headers.Accept
设置为*/*
1.当POSTMAN中的Body的“预览”呈现PDF或图像时,您将知道一切都正常工作。如果您没有预览-当从bytes(postman)-〉b64 string(api网关)-〉bytes(S3存储)-〉b64 string(api网关)-〉bytes(postman)转换时,字节仍然会损坏。
这绝对是您在GoLang for AWS Lambda中使用API Gateway作为代理处理二进制有效载荷所需的一切。从POSTMAN迁移到浏览器时,不要忘记CORS!