如何使用AWS SAM为API Gateway HttpApi配置自定义域名
问题原因
你触发报错的核心原因是资源类型不匹配:你使用的AWS::Serverless::HttpApi属于API Gateway V2(HTTP API)资源,但你配置的AWS::ApiGateway::DomainName、AWS::ApiGateway::BasePathMapping属于API Gateway V1(REST API)的资源类型,二者不能混用。
具体修改方案
1. 替换根栈的域名与映射资源为V2版本
将原根栈中的AppDomainName和APIBasePathMapping资源替换为如下配置:
# 根栈中的V2域名配置 AppDomainName: Type: AWS::ApiGatewayV2::DomainName Properties: DomainName: !Ref DomainName DomainNameConfigurations: - CertificateArn: arn:aws:acm:us-east-1:xxxxxxx43:certificate/1axxxf-3234-xxx2f-a61c-924eeexxxx9 EndpointType: REGIONAL # 如果要用边缘端点就改EDGE,注意EDGE类型的证书必须部署在us-east-1区域 SecurityPolicy: TLS_1_2 # 根栈的API路径映射 APIRootMapping: Type: AWS::ApiGatewayV2::ApiMapping Properties: ApiId: !Ref AuthGatewayHttpApi DomainName: !Ref AppDomainName Stage: $default # SAM HttpApi默认的stage名称是$default,不是default # ApiMappingKey如果留空,就直接把根栈API的路由挂载到域名根路径,比如/accountingtypes/getall直接对应api.mydomain.com/accountingtypes/getall # 如果要加前缀可以填对应的值,比如填api的话路径就是api.mydomain.com/api/accountingtypes/getall
2. 调整嵌套栈配置,共用根栈的HTTP API
你当前嵌套栈中单独定义了AuthGatewayHttpApi,相当于创建了独立的第二个HTTP API,无法统一挂载到同一个域名下。需要做如下修改:
- 嵌套栈新增
SharedHttpApiId参数,删除嵌套栈内的AuthGatewayHttpApi资源定义 - 嵌套栈内所有函数的
Events配置中,ApiId改为引用!Ref SharedHttpApiId参数 - 根栈调用嵌套栈时,把根栈的
AuthGatewayHttpApi的ID作为参数传递给嵌套栈
调整后的嵌套栈参数示例:
# 嵌套栈的参数部分新增SharedHttpApiId Parameters: FirebaseProjectId: Type: String SharedHttpApiId: Type: String # 嵌套栈内删除AuthGatewayHttpApi资源定义,所有函数的ApiId引用SharedHttpApiId GetAllPromotionsFunction: Type: AWS::Serverless::Function Properties: CodeUri: aws-restapi/ Handler: source/promotions/promotions-getall.getAllPromotions Runtime: nodejs14.x Events: GetAllPromotionsAPIEvent: Type: HttpApi Properties: Path: /promotions/getall Method: get ApiId: !Ref SharedHttpApiId
根栈中调用嵌套栈的示例:
# 根栈中嵌套栈的定义示例 PromotionNestedStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: ./path/to/your/nested/stack/template.yaml Parameters: FirebaseProjectId: !Ref FirebaseProjectId SharedHttpApiId: !Ref AuthGatewayHttpApi
3. 额外配置提醒
- 域名解析需要添加对应的CNAME记录,指向
AppDomainName资源返回的RegionalDomainName(如果是区域端点)或者DistributionDomainName(如果是边缘端点) - 如果要给不同模块的API配置不同的路径前缀,可以给每个嵌套栈单独创建
AWS::ApiGatewayV2::ApiMapping,设置对应的ApiMappingKey作为前缀即可
内容的提问来源于stack exchange,提问作者PeakGen
相关产品推荐
相关产品推荐

