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

无法自定义.NET Lambda Annotations Framework生成的HTTP API Gateway

.NET Lambda注解框架自定义HTTP API网关失效问题

我用.NET Lambda Annotations Framework定义了如下GET端点:

[LambdaFunction]
[HttpApi(LambdaHttpMethod.Get, "/info")]
public string FunctionHandler(ILambdaContext context)
{
    return "OK";
}

生成的serverless.template会通过CloudFormation自动创建HTTP API Gateway、集成和路由,一切运行正常:

"TestFunctionFunctionHandlerGenerated": {
  "Type": "AWS::Serverless::Function",
  "Metadata": {
    "Tool": "Amazon.Lambda.Annotations",
    "SyncedEvents": [
      "RootGet"
    ],
    "SyncedEventProperties": {
      "RootGet": [
        "Path",
        "Method"
      ]
    }
  },
  "Properties": {
    "Runtime": "dotnet8",
    "CodeUri": ".",
    "MemorySize": 512,
    "Timeout": 30,
    "Policies": [
      "AWSLambdaBasicExecutionRole"
    ],
    "PackageType": "Zip",
    "Handler": "Test::Test.Function_FunctionHandler_Generated::FunctionHandler",
    "FunctionName": "TestGetInfo",
    "Events": {
      "RootGet": {
        "Type": "HttpApi",
        "Properties": {
          "Path": "/info",
          "Method": "GET"
        }
      }
    }
  }
}

但当我尝试自定义该HTTP API Gateway(比如配置CorsConfiguration或附加JWT授权器)时,始终无法生效。我曾尝试添加与现有网关逻辑ID匹配的HTTP API Gateway并在端点中引用,但没有效果(见2024-07-07编辑)。

目前唯一可行的方式是让注解框架生成函数部分,再手动创建API网关、路由、集成及绑定,但这会失去注解带来的所有优势,操作非常繁琐:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.5.0.0).",
  "Resources": {
    "TestApi": {
      "Type": "AWS::ApiGatewayV2::Api",
      "Properties": {
        "Name": "Test-api",
        "ProtocolType": "HTTP",
        "CorsConfiguration": {
          "AllowOrigins": [
            "*"
          ],
          "AllowMethods": [
            "GET",
            "POST",
            "DELETE",
            "OPTIONS",
            "PUT",
            "PATCH"
          ],
          "AllowHeaders": [
            "Content-Type",
            "Authorization"
          ],
          "MaxAge": 600
        }
      }
    },
    "TestApiIntegration": {
      "Type": "AWS::ApiGatewayV2::Integration",
      "Properties": {
        "ApiId": {
          "Ref": "TestApi"
        },
        "IntegrationType": "AWS_PROXY",
        "IntegrationUri": {
          "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TestFunctionFunctionHandlerGenerated.Arn}/invocations"
        },
        "PayloadFormatVersion": "2.0"
      }
    },
    "TestApiRoute": {
      "Type": "AWS::ApiGatewayV2::Route",
      "Properties": {
        "ApiId": {
          "Ref": "TestApi"
        },
        "RouteKey": "GET /info",
        "Target": {
          "Fn::Sub": "integrations/${TestApiIntegration}"
        }
      }
    },
    "TestApiDeployment": {
      "Type": "AWS::ApiGatewayV2::Deployment",
      "Properties": {
        "ApiId": {
          "Ref": "TestApi"
        }
      },
      "DependsOn": [
        "TestApiRoute"
      ]
    },
    "TestApiStage": {
      "Type": "AWS::ApiGatewayV2::Stage",
      "Properties": {
        "ApiId": {
          "Ref": "TestApi"
        },
        "StageName": "prod",
        "DeploymentId": {
          "Ref": "TestApiDeployment"
        },
        "AutoDeploy": true
      }
    },
    "TestFunctionFunctionHandlerGenerated": {
      "Type": "AWS::Serverless::Function",
      "Metadata": {
        "Tool": "Amazon.Lambda.Annotations",
        "SyncedEvents": [
          "RootGet"
        ],
        "SyncedEventProperties": {
          "RootGet": [
            "Path",
            "Method"
          ]
        }
      },
      "Properties": {
        "Runtime": "dotnet8",
        "CodeUri": ".",
        "MemorySize": 512,
        "Timeout": 30,
        "Policies": [
          "AWSLambdaBasicExecutionRole"
        ],
        "PackageType": "Zip",
        "Handler": "Test::Test.Function_FunctionHandler_Generated::FunctionHandler",
        "FunctionName": "TestGetInfo",
        "Events": {
          "RootGet": {
            "Type": "HttpApi",
            "Properties": {
              "Path": "/info",
              "Method": "GET",
              "ApiId": {
                "Ref": "TestApi"
              }
            }
          }
        }
      }
    }
  },
  "Outputs": {
    "TestApi": {
      "Value": {
        "Fn::Sub": "${TestApi}"
      },
      "Export": {
        "Name": "TestApi"
      }
    },
    "HttpApiGatewayUrl": {
      "Value": {
        "Fn::Sub": "https://${TestApi}.execute-api.${AWS::Region}.amazonaws.com"
      }
    }
  }
}

2024-07-07 编辑

CloudFormation堆栈信息:

Logical IDPhysical IDTypeStatus
ServerlessHttpApiMASKEDAWS::ApiGatewayV2::ApiCREATE_COMPLETE
ServerlessHttpApiApiGatewayDefaultStage$defaultAWS::ApiGatewayV2::StageCREATE_COMPLETE
TestFunctionFunctionHandlerGeneratedTestGetInfoAWS::Lambda::FunctionCREATE_COMPLETE
TestFunctionFunctionHandlerGeneratedRoleMASKEDAWS::IAM::RoleCREATE_COMPLETE
TestFunctionFunctionHandlerGeneratedRootGetPermissionMASKEDAWS::Lambda::PermissionCREATE_COMPLETE

完整的serverless.template:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.5.0.0).",
  "Resources": {
    "ServerlessHttpApi": {
      "Type": "AWS::ApiGatewayV2::Api",
      "Properties": {
        "Name": "test-api",
        "ProtocolType": "HTTP",
        "CorsConfiguration": {
          "AllowOrigins": [
            "*"
          ],
          "AllowMethods": [
            "POST"
          ],
          "AllowHeaders": [
            "Content-Type",
            "Authorization"
          ],
          "MaxAge": 600
        }
      }
    },
    "TestFunctionFunctionHandlerGenerated": {
      "Type": "AWS::Serverless::Function",
      "Metadata": {
        "Tool": "Amazon.Lambda.Annotations",
        "SyncedEvents": [
          "RootGet"
        ],
        "SyncedEventProperties": {
          "RootGet": [
            "Path",
            "Method"
          ]
        }
      },
      "Properties": {
        "Runtime": "dotnet8",
        "CodeUri": ".",
        "MemorySize": 512,
        "Timeout": 30,
        "Policies": [
          "AWSLambdaBasicExecutionRole"
        ],
        "PackageType": "Zip",
        "Handler": "Test::Test.Function_FunctionHandler_Generated::FunctionHandler",
        "FunctionName": "TestGetInfo",
        "Events": {
          "RootGet": {
            "Type": "HttpApi",
            "Properties": {
              "Path": "/info",
              "Method": "GET",
              "ApiId": {
                "Ref": "ServerlessHttpApi"
              }
            }
          }
        }
      }
    }
  },
  "Outputs": {
    "HttpApiGatewayUrl": {
      "Value": {
        "Fn::Sub": "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com"
      }
    }
  }
}

即便我将CORS设置为仅允许POST请求(测试用),GET请求仍能正常返回"OK",且AWS控制台中也看不到任何更改:https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com/info


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:42:02