aws / aws-lambda-dotnet

Libraries, samples and tools to help .NET Core developers develop AWS Lambda functions.
Apache License 2.0
1.56k stars 480 forks source link

Support development time local HTTP server with Amazon.Lambda.Annotations #1040

Open vivainio opened 2 years ago

vivainio commented 2 years ago

Describe the Feature

When writing serverless functions that are used from behind API gateway (esp. backend to a browser frontend), it's useful to be able to use them on localhost without API Gateway, e.g. through a browser.

This is not currently supported in Amazon.Lambda.Annotations, but is supported in ASP.Net lambda templates https://aws.amazon.com/blogs/developer/running-serverless-asp-net-core-web-apis-with-amazon-lambda/

Similar solutions exist for other platforms, e.g.:

Describe alternatives you've considered

Use ASPNet.Core template instead of Amazon.Lambda.Annotations

This is a :rocket: Feature Request

ganeshnj commented 2 years ago

I was thinking ways to support local debugging like a localhost server Lambda.Annotations.

I think, we can generate code for a ASP.NET Core Web API app along which has same set of controller actions as customer has specified as LambdaFunctions along with mapping the parameters with ASP.NET Core request parameters.

    public class SimpleCalculator
    {
        private readonly ISimpleCalculatorService _simpleCalculatorService;

        /// <summary>
        /// Default constructor that Lambda will invoke.
        /// </summary>
        public SimpleCalculator(ISimpleCalculatorService simpleCalculatorService)
        {
            this._simpleCalculatorService = simpleCalculatorService;
        }

        [LambdaFunction(Name = "SimpleCalculatorAdd", PackageType = LambdaPackageType.Image)]
        [RestApi(HttpMethod.Get, "/SimpleCalculator/Add")]
        public int Add([FromQuery]int x, [FromQuery]int y)
        {
            return _simpleCalculatorService.Add(x, y);
        }
}

generates

    [Route("SimpleCalculator")]
    [ApiController]
    public class SimpleCalculatorController : ControllerBase
    {
        private readonly SimpleCalculator simpleCalculator;

        public SimpleCalculatorController(SimpleCalculator simpleCalculator)
        {
            this.simpleCalculator = simpleCalculator;
        }

        [HttpGet("Add")]
        public string Add([FromQuery]int x, [FromQuery]int y)
        {
            return simpleCalculator.Add(x, y);
        }
    }
    public class Startup
    {
...
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddSingleton(new SimpleCalculator());
        }
...
    }

And now when running locally, you can hit https://localhost:44312/SimpleCalculator/Add?x=1&y=2 from local apps.

vivainio commented 2 years ago

You can avoid generating Controllers by using the new Minimal API approach: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0

ganeshnj commented 2 years ago

I have not played a lot with minimal APIs, worth considering this option given Lambda Annotations are for .NET 6 or above only.

normj commented 2 years ago

@vivainio If your existing .NET Lambda test tool exposed calling the Lambda functions via the REST endpoint defined in the CloudFormation template would that meet your expectations?

vivainio commented 2 years ago

@normj if that test tools was listening for HTTP requests on localhost and forwarding the calls to the lambda via "proxy" resource, then yes. Similarly to how the aspnet.core template works (unless the recommendation is to use aspnet.core for applications like this)