Skip to content

Design Doc: Lambda Annotation #979

Closed

Description

@normj

The AWS .NET team is working on a new library for constructing .NET Lambda functions. The design doc can be viewed and commented on in this PR #961.

The high level overview of the new library is to use .NET source generator support to translating from the low level single event object programming model of Lambda to an experience similar to ASP.NET Core but with minimal overhead. The initial work is focused on REST API Lambda functions but the technology is applicable for other Lambda event types.

For example developers will be able to write a Lambda function like the following with the ICalculator service being injected by dependency injection and and the LambdaFunction and HttpApi attributes directing the source generator to generator the compatible Lambda boiler plate code and sync with the CloudFormation template.

public class Functions
{
	ICalculator _calulator;

	public Functions(ICalculator calculator)
	{
		_calulator = calculator;
	}

	[LambdaFunction]
	[HttpApi(HttpMethod.Get, HttpApiVersion.V2, "/add/{x}/{y}")]
	public int Add(int x, int y)
	{
		return _calulator.Add(x, y);
	}
}

We would appreciate feedback on the design. What use cases what you like this library to help solve and what boiler plate code can we remove from your applications to make it simple to write Lambda functions.


Update 12/21/2021

We are excited to announce that Lambda Annotations first preview is here. Developers using the preview version of Amazon.Lambda.Annotations NuGet package can start using the simplified programming model to write REST and HTTP API Lambda functions on .NET 6. (Only Image package type is supported as of now)

Example (sample project)

[LambdaFunction(Name = "CalculatorAdd", PackageType = LambdaPackageType.Image)]
[RestApi(HttpMethod.Get, "/Calculator/Add/{x}/{y}")]
public int Add(int x, int y, [FromServices]ICalculatorService calculatorService)
{
    return calculatorService.Add(x, y);
}
[LambdaStartup]
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<ICalculatorService, CalculatorService>();
    }
}

Learn more about the Lambda Annotations and supported feature set here.

We cannot overstate how critical your feedback is as we move forward in the development. Let us know your experience working with Lambda Annotations in GitHub issues.

Activity

  1. added
    guidanceQuestion that needs advice or information.
    needs-triageThis issue or PR still needs to be triaged.
    on Nov 17, 2021
  2. pinned this issue on Nov 17, 2021
  3. added and removed
    guidanceQuestion that needs advice or information.
    needs-triageThis issue or PR still needs to be triaged.
    on Nov 17, 2021
  4. CalvinAllen commented on Nov 17, 2021

    @CalvinAllen

    Dependency Injection is a huge plus, to me. I've had to roll that myself to support it - same with logging and configuration / environmental configuration.

    EDIT: Why confused, @normj ?

  5. Lanayx commented on Nov 17, 2021

    @Lanayx
    Contributor

    Source generators is not dotnet, but csharp technology, so will be applicable only to csharp, with fsharp it won't be usable.

  6. mtschneiders commented on Nov 17, 2021

    @mtschneiders

    Would it also generate the code needed for manual invocation via Lambda Test Tool?

     public static async Task Main()
      {
          var func = new Startup().FunctionHandler;
          using var handlerWrapper = HandlerWrapper.GetHandlerWrapper(func, new DefaultLambdaJsonSerializer());
          using var bootstrap = new LambdaBootstrap(handlerWrapper);
          await bootstrap.RunAsync();
      }
  7. normj commented on Nov 17, 2021

    @normj
    MemberAuthor

    Dependency Injection is a huge plus, to me. I've had to roll that myself to support it - same with logging and configuration / environmental configuration.

    EDIT: Why confused, @normj ?

    @CalvinAllen Sorry clicked the wrong emoji

  8. CalvinAllen commented on Nov 17, 2021

    @CalvinAllen

    @normj Ha, okay. I was a little confused myself, trying to figure out what I said, lol.

  9. Kralizek commented on Nov 17, 2021

    @Kralizek

    It would be great to see more of the plumbing, which happened to be the weakest point of Lambda development.

    As @CalvinAllen wrote, logging, configuration and service registration are all concerns that required some time to work in a vanilla function.

    But I generally love the idea of seeing multi-function packages becoming first class citizen of the new toolkit.

  10. petarrepac commented on Nov 17, 2021

    @petarrepac

    why is this being introduced ?
    what problems it solves ?
    what are expected benefits over the current approach?
    what are the downsides ?

  11. normj commented on Nov 18, 2021

    @normj
    MemberAuthor

    why is this being introduced ? what problems it solves ? what are expected benefits over the current approach? what are the downsides ?

    @petarrepac Are you saying these questions are not answered in the design doc?

  12. 38 remaining items

  13. normj commented on Aug 2, 2022

    @normj
    MemberAuthor

    Version 0.6.0-preview has been released. It contains a breaking change to move the API Gateway .NET attributes to a new Amazon.Lambda.Annotations.APIGateway namespace. We wanted to make sure when we add more services that we would not make the root namespace Amazon.Lambda.Annotations too confusing or run into conflicts.

    Due to the breaking change and the way source generators work if you update your project you might need to restart Visual Studio after updating. Otherwise the events section in the CloudFormation template might disappear.

    Note, we avoid making breaking changes as much as possible but since this is in preview and it is important we set our selves up for the future we think this breaking change is warranted.

    There are also a couple other fixes dealing with functions that return null and making sure the CloudFormation is synced when all of the LambdaFunctionAttribute are removed.

  14. Simonl9l commented on Aug 2, 2022

    @Simonl9l

    @normj thanks for the update.

    For the time being we’re sticking with the dotnet 6 minimal API setup given need for ALB bindings, and related issues below.

    We figure it’s minimal effort to switch over to the annotations library as it progresses…

    Our main issues as it stand is not the annotations library itself but the tool support either via the lambda test tools - not supporting the lambda lifecycle, or the Rider AWS toolkit support at all in a reliable way we can use access the dev team.

    We have issues opened on both.

    We’re also interested to see where any CDK integration goes. Including Docker and Extensions support. We’ve been experimenting with Local Stack such that our dev env fully replicates our eventual production deployment stack, and have been able to deploy and test lambdas locally.

    We realize you have limited capacity/resources in the dotnet space, but are exited at your continued efforts and your ongoing commitment to make it’s support equivalent of other languages.

  15. ryanpsm commented on Aug 17, 2022

    @ryanpsm

    @normj If I want to return different HTTP status codes and error messages depending on the issue that arose during processing the request, is that possible with the Annotations API?

    The regular Lambda model has returns such as:

    return new APIGatewayHttpApiV2ProxyResponse {
        StatusCode = (int)HttpStatusCode.BadRequest,
        Body = "Failed to process request due to invalid type parameter."
        Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
    };
    
    return new APIGatewayHttpApiV2ProxyResponse {
            StatusCode = (int)HttpStatusCode.OK,
            Body = "Successfully sent message.",
            Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
    };

    And the new version from the examples is as far as I can tell just:

    return "Successfully sent message.";
  16. normj commented on Aug 29, 2022

    @normj
    MemberAuthor

    @ryanpsm With the Annotations library you can still return the APIGatewayHttpApiV2ProxyResponse to customize the status codes and headers returned. I have thought about creating an optional base class that could have the familiar Ok, NotFound and other base methods for a better experience. Curious what others thoughts are on that.

  17. normj commented on Aug 29, 2022

    @normj
    MemberAuthor

    Version 0.7.0-preview is out that adds YAML support and fixes a code generation issue.

  18. danielsunnerberg commented on Dec 13, 2022

    @danielsunnerberg

    @ryanpsm With the Annotations library you can still return the APIGatewayHttpApiV2ProxyResponse to customize the status codes and headers returned. I have thought about creating an optional base class that could have the familiar Ok, NotFound and other base methods for a better experience. Curious what others thoughts are on that.

    This is my exact use-case (related discussion thread). Preferably I'd like to avoid building the response body myself (serialization etc). Perhaps throwing an exception could be an option?

  19. Simonl9l commented on Jan 28, 2023

    @Simonl9l

    Per the comments above from @ganeshnj related to application/x-www-form-urlencoded we're currently using the Minimal API and AddAWSLambdaHosting that is fine when debugging as its using Kestrel locally; but fails miserably once we put the Lambda behind and API Gateway and it swaps in the Lambda bootstrapping process.

    From an API Gateway perspective it seems a common patterns related to this to the use a Request Transform to convert the Form payload onto a JSON one, however that then makes local debugging a pain as one does not have the transform in place.

    We've opened an issue (#1423) more related to AddAWSLambdaHosting in this regard, as It's not clearly documented as to what happens with custom middleware related to the Lambda Hosting, or one could implement the equivalent transform there.

    We figured any builtin support in the Annotation library to support this context type more directly would definitely be valuable.

    As a related use case the Stipe payments system uses Forms for its hosted Checkout and Customer Portals - as it uses redirects from the web client to achieve the workflow. Surely others either do, or might plan to, host Lambdas to support their Stripe integration if this is more easily supported.

  20. normj commented on Feb 8, 2023

    @normj
    MemberAuthor

    We released version 0.11.0 of the library today that provides greater control over the response for API Gateway based events. Checkout below for an example and please let us know what you think.

    [LambdaFunction]
    [HttpApi(LambdaHttpMethod.Get, "/{id}")]
    public IHttpResult GetOrder(string id)
    {
        var order = FetchOrderInfo(id);
        if(order == null)
        {
            return HttpResults.NotFound()
                                .AddHeader("custom-header", "value");
        }
    
        return HttpResults.Ok(order);
    }
  21. danielsunnerberg commented on Feb 9, 2023

    @danielsunnerberg

    We released version 0.11.0 of the library today that provides greater control over the response for API Gateway based events. Checkout below for an example and please let us know what you think.

    [LambdaFunction]
    [HttpApi(LambdaHttpMethod.Get, "/{id}")]
    public IHttpResult GetOrder(string id)
    {
        var order = FetchOrderInfo(id);
        if(order == null)
        {
            return HttpResults.NotFound()
                                .AddHeader("custom-header", "value");
        }
    
        return HttpResults.Ok(order);
    }

    Exactly what I was looking for, many thanks!

  22. NickBittar commented on Mar 15, 2023

    @NickBittar

    Really love what you're doing with this library. I noticed in the design document there are mentions of adding middleware and a configure method in the Startup.cs here. I haven't seen it mentioned much outside of this document. I was wondering, is this still a planned feature to add?

  23. normj commented on Mar 16, 2023

    @normj
    MemberAuthor

    @NickBittar thanks for the feedback. It is still the plan to add middleware support. Not sure if it will be in the 1.0 version because we would really like to get the library past the preview state.

  24. normj commented on Jul 17, 2023

    @normj
    MemberAuthor

    We released the 1.0 GA version of Lambda Annotations: https://aws.amazon.com/blogs/developer/net-lambda-annotations-framework/

    I'm going to close this design issue now that we have reached GA status. This does not mean we are done and there is more feature we want to implement like the middleware abstraction and other events. That work will be tracked in separate issues and PRs.

    Please keep the feedback coming and feel free to open issues for feature requests or any issues you run in.

  25. unpinned this issue on Jul 17, 2023
  26. github-actions commented on Jul 17, 2023

    @github-actions
    Contributor

    ⚠️COMMENT VISIBILITY WARNING⚠️

    Comments on closed issues are hard for our team to see.
    If you need more assistance, please either tag a team member or open a new issue that references this one.
    If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions