Add [FunctionUrl] annotation attribute with CORS support and source generator#2324
Add [FunctionUrl] annotation attribute with CORS support and source generator#2324GarrettBeatty wants to merge 2 commits intodevfrom
Conversation
5bfe161 to
6d32835
Compare
There was a problem hiding this comment.
Pull request overview
Adds first-class Lambda Function URL support to the Lambda Annotations framework, including SAM FunctionUrlConfig emission, optional CORS configuration, and end-to-end tests (unit + integration) to validate generation and invocation behavior.
Changes:
- Introduces
[FunctionUrl]+FunctionUrlAuthTypeinAmazon.Lambda.Annotations.APIGatewayand wires it into the source generator’s discovery/model building. - Updates CloudFormation template writing to emit
FunctionUrlConfig(and optionalCors) on the function resource and to remove the config when the attribute is removed. - Adds generator snapshot tests, CloudFormation writer tests, and a deployed integration test example that calls the Function URL and validates logs/config.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Libraries/test/TestServerlessApp/serverless.template | Adds a generated function resource that includes FunctionUrlConfig. |
| Libraries/test/TestServerlessApp/FunctionUrlExample.cs | Adds a sample Lambda handler annotated with [FunctionUrl]. |
| Libraries/test/TestServerlessApp/aws-lambda-tools-defaults.json | Updates default stack/bucket naming used by integration deployment. |
| Libraries/test/TestServerlessApp.IntegrationTests/IntegrationTestContextFixture.cs | Discovers and stores the deployed Function URL for integration tests; updates expected function count. |
| Libraries/test/TestServerlessApp.IntegrationTests/FunctionUrlExample.cs | Adds integration tests for invoking the Function URL, validating response/logging/config. |
| Libraries/test/IntegrationTests.Helpers/LambdaHelper.cs | Adds helper to fetch GetFunctionUrlConfig from Lambda. |
| Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/FunctionUrlTests.cs | Adds CloudFormation writer unit tests for Function URL config and CORS emission/removal/switching. |
| Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs | Adds snapshot-based source generator test coverage for Function URL generation. |
| Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/functionUrlExample.template | Adds expected serverless template snapshot for Function URL output. |
| Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/FunctionUrlExample_GetItems_Generated.g.cs | Adds expected generated handler snapshot for a Function URL endpoint. |
| Libraries/src/Amazon.Lambda.Annotations/APIGateway/FunctionUrlAuthType.cs | Introduces auth mode enum for Function URLs. |
| Libraries/src/Amazon.Lambda.Annotations/APIGateway/FunctionUrlAttribute.cs | Introduces [FunctionUrl] attribute including optional CORS properties. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/CloudFormationWriter.cs | Emits/removes FunctionUrlConfig and emits optional Cors block for Function URLs. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Validation/LambdaFunctionValidator.cs | Ensures required dependency on Amazon.Lambda.APIGatewayEvents when [FunctionUrl] is used. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs | Registers full type names for new Function URL types. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/SyntaxReceiver.cs | Treats [FunctionUrl] as a “secondary attribute” requiring [LambdaFunction] for diagnostics. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs | Forces Function URL handlers to use HTTP API v2 request/response types. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs | Classifies [FunctionUrl] as an API-type event for validation/behavior. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FunctionUrlAttributeBuilder.cs | Builds the FunctionUrlAttribute model from Roslyn AttributeData. |
| Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs | Adds [FunctionUrl] to attribute model building pipeline. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Writers/CloudFormationWriter.cs
Show resolved
Hide resolved
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/WriterTests/FunctionUrlTests.cs
Show resolved
Hide resolved
...c/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FunctionUrlAttributeBuilder.cs
Outdated
Show resolved
Hide resolved
| NONE, | ||
|
|
||
| /// <summary> | ||
| /// IAM authentication. Only authenticated IAM users and roles can invoke the function. | ||
| /// </summary> | ||
| AWS_IAM |
There was a problem hiding this comment.
FunctionUrlAuthType introduces enum members in ALL_CAPS (NONE, AWS_IAM), which is inconsistent with the rest of the public enums in this package (e.g., LambdaHttpMethod.Get, HttpApiVersion.V2). Consider using PascalCase member names (e.g., None, AwsIam) and mapping to the SAM-required strings in the template writer (so public API stays idiomatic while still emitting NONE/AWS_IAM).
| NONE, | |
| /// <summary> | |
| /// IAM authentication. Only authenticated IAM users and roles can invoke the function. | |
| /// </summary> | |
| AWS_IAM | |
| None, | |
| /// <summary> | |
| /// IAM authentication. Only authenticated IAM users and roles can invoke the function. | |
| /// </summary> | |
| AwsIam |
There was a problem hiding this comment.
i think it should be all caps
| @@ -0,0 +1,18 @@ | |||
| namespace Amazon.Lambda.Annotations.APIGateway | |||
There was a problem hiding this comment.
technically function url is completely different than api gateway but uses the same api gateway v2 response type, so i kept it in the same namespace for now
…oudFormation FunctionUrlConfig generation - New FunctionUrlAttribute class with AuthType property (NONE/AWS_IAM) - New FunctionUrlAuthType enum - Source generator detects FunctionUrlAttribute and maps to EventType.API - Generated wrapper uses HttpApi V2 request/response types (same payload format) - CloudFormationWriter emits FunctionUrlConfig on the function resource - Dependency validation checks for Amazon.Lambda.APIGatewayEvents - SyntaxReceiver detects missing [LambdaFunction] on [FunctionUrl] methods - 6 new unit tests for CloudFormation template generation (JSON + YAML) Phase 2: Add CORS support to FunctionUrlAttribute - AllowOrigins, AllowMethods, AllowHeaders, ExposeHeaders, AllowCredentials, MaxAge properties - FunctionUrlAttributeBuilder parses all CORS properties from AttributeData - CloudFormationWriter emits Cors block under FunctionUrlConfig only when CORS properties are set - 4 new unit tests for CORS generation and no-CORS scenarios Phase 3: FunctionUrlConfig orphan cleanup and attribute switching - Remove FunctionUrlConfig from template when [FunctionUrl] attribute is removed - Clean transition when switching from [FunctionUrl] to [HttpApi] or [RestApi] - 4 new unit tests for orphan cleanup and attribute switching scenarios Phase 4: End-to-end source generator test for FunctionUrl - FunctionUrlExample.cs test source with [FunctionUrl] + [FromQuery] + IHttpResult - Generated wrapper snapshot using HttpApi V2 payload format - Serverless template snapshot with FunctionUrlConfig - Full Roslyn source generator verification test IT tests Update Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FunctionUrlAttributeBuilder.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> copilot comments change file fix cleanup
02102ad to
41ed661
Compare
...c/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FunctionUrlAttributeBuilder.cs
Show resolved
Hide resolved
Libraries/src/Amazon.Lambda.Annotations/APIGateway/FunctionUrlAttribute.cs
Show resolved
Hide resolved
Libraries/src/Amazon.Lambda.Annotations/APIGateway/FunctionUrlAuthType.cs
Show resolved
Hide resolved
| /// <summary> | ||
| /// The allowed HTTP methods for CORS requests. Example: new[] { "GET", "POST" } | ||
| /// </summary> | ||
| public string[] AllowMethods { get; set; } |
There was a problem hiding this comment.
I think we should be using an enum like we do in the API Gateway events. For the API Gateway we created our own enum to support "Any". Not sure if that is a valid situation here or is the absence of this property essentially "Any".
Add
[FunctionUrl]annotation attribute with CORS support and source generatorWhat is this?
Adds first-class support for Lambda Function URLs to the Lambda Annotations framework. Function URLs give your Lambda function a dedicated HTTPS endpoint without needing API Gateway — ideal for webhooks, simple APIs, and microservices.
Usage
This generates a handler that accepts HTTP API v2 payloads and emits a
FunctionUrlConfigin your SAM template — no API Gateway resource needed.CORS support
CORS configuration is optional — the
Corsblock is only emitted when at least one CORS property is set.Authentication
Two auth modes via
FunctionUrlAuthType:NONE— Public endpoint, anyone with the URL can invoke the functionAWS_IAM— Only authenticated IAM users/roles can invoke the functionKey points
APIGatewayHttpApiV2ProxyRequest/Response), so the source generator always uses v2 types — there is no version selection like[HttpApi]has[FromQuery],[FromHeader],[FromBody],[FromRoute]) andIHttpResultreturns work out of the boxFunctionUrlConfigas a property on the function resource (not as an event source), matching the SAM specificationFunctionUrlConfigfrom the template when the attribute is removed[FunctionUrl]and[HttpApi]/[RestApi]seamlessly[FunctionUrl]without[LambdaFunction]and reports a diagnostic errorRelated: DOTNET-8569