如何通过serverless.yml配置API Gateway REST API无Lambda传文件至S3
可以通过Serverless.yml实现无Lambda的API Gateway直接上传文件到S3
是的,你可以不依赖Lambda,直接通过API Gateway的集成请求将文件上传到S3。Serverless Framework本身没有专门的简化配置,但可以通过在serverless.yml中定义自定义CloudFormation资源来实现——因为Serverless的配置本质是基于CloudFormation扩展的。
实现思路
API Gateway支持直接与S3集成,通过配置AWS_PROXY类型的集成请求,将上传的文件直接转发到S3存储桶。需要完成以下关键配置:
- 创建API Gateway的REST API资源和方法(比如POST方法)
- 配置该方法的集成请求,目标指向S3存储桶,设置正确的权限和路径映射
- 确保API Gateway有足够的权限向S3写入文件
示例Serverless.yml配置
以下是一个完整的示例配置,包含S3存储桶创建、API Gateway集成以及必要的IAM权限:
service: s3-direct-upload-api provider: name: aws runtime: python3.9 # 此处指定runtime仅为框架兼容要求,实际不会用到Lambda region: us-east-1 resources: Resources: # 创建S3存储桶 UploadBucket: Type: AWS::S3::Bucket Properties: BucketName: my-direct-upload-bucket-${self:provider.stage} CorsConfiguration: CorsRules: - AllowedHeaders: ["*"] AllowedMethods: ["POST", "PUT"] AllowedOrigins: ["*"] # 生产环境请根据实际需求限制来源 # API Gateway REST API实例 UploadApi: Type: AWS::ApiGateway::RestApi Properties: Name: S3DirectUploadAPI-${self:provider.stage} # API Gateway上传路径资源(/upload) UploadResource: Type: AWS::ApiGateway::Resource Properties: ParentId: !GetAtt UploadApi.RootResourceId PathPart: upload RestApiId: !Ref UploadApi # 带文件名参数的子资源(/upload/{filename}) UploadFileResource: Type: AWS::ApiGateway::Resource Properties: ParentId: !Ref UploadResource PathPart: "{filename}" RestApiId: !Ref UploadApi # POST方法配置,直接集成S3 UploadPostMethod: Type: AWS::ApiGateway::Method Properties: AuthorizationType: NONE # 生产环境请配置合适的认证方式(如IAM、Cognito) HttpMethod: POST Integration: Credentials: !GetAtt ApiGatewayS3Role.Arn IntegrationHttpMethod: PUT # 映射为S3的PUT上传操作 Type: AWS_PROXY Uri: !Sub "arn:aws:apigateway:${self:provider.region}:s3:path/${UploadBucket}/{filename}" RequestParameters: integration.request.path.filename: "method.request.path.filename" integration.request.header.Content-Type: "method.request.header.Content-Type" MethodResponses: - StatusCode: 200 RequestParameters: method.request.path.filename: true method.request.header.Content-Type: true RestApiId: !Ref UploadApi ResourceId: !Ref UploadFileResource # API Gateway部署 ApiDeployment: Type: AWS::ApiGateway::Deployment Properties: RestApiId: !Ref UploadApi StageName: ${self:provider.stage} DependsOn: - UploadPostMethod # 给API Gateway赋予S3写入权限的IAM角色 ApiGatewayS3Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: apigateway.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: ApiGatewayS3UploadPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - s3:PutObject Resource: !Sub "${UploadBucket.Arn}/*" Outputs: ApiEndpoint: Value: !Sub "https://${UploadApi}.execute-api.${self:provider.region}.amazonaws.com/${self:provider.stage}/upload/{filename}"
关键说明
- 通过
AWS::ApiGateway::Method配置AWS_PROXY类型集成,将POST请求转换为S3的PUT操作,实现直接上传 ApiGatewayS3Role专门授权API Gateway向目标S3存储桶执行PutObject操作- CORS配置用于支持前端直接上传,生产环境需严格限制
AllowedOrigins - 部署完成后,可通过
Outputs中的API端点,发送包含文件内容的POST请求到https://<api-id>.execute-api.<region>.amazonaws.com/<stage>/upload/<your-filename>,直接上传文件到S3
为什么Serverless文档里没提到?
Serverless Framework的核心设计围绕Lambda函数展开,大部分官方示例和简化配置都是针对Lambda触发的场景。无Lambda的API Gateway集成属于更底层的CloudFormation配置,需要手动定义资源,因此官方文档没有专门章节讲解,但完全支持通过自定义资源实现。
内容的提问来源于stack exchange,提问作者chvc
相关产品推荐
相关产品推荐

