Build an API Gateway with Lambda Function in dotnet Core

Overview

There is an AWS Extension available for Visual Studio. AWS Toolkit for Visual Studio 2017 can be added as an extension to Microsoft Visual Studio 2017.

AWS Toolkit for VS2017

After the installation completed, a project template to create “AWS Serverless Application (.Net Core)” will be available to start Serverless ASP.Net Core Web Api.

But in this post, I am taking a different approach. I am adding all the bits and pieces by myself to understand what is required for a Serverless API with a lambda function

Serverless API with AWS Lambda

The source code is available on Gitbub.

Here, I am starting with an empty asp dotnet Core Web Application.

A new ASP.Net Core Web Application

Program.cs is the local entry point for the application. The Main function can be used to run the ASP.NET Core application locally using the Kestrel webserver. We need another class to extends APIGatewayProxyFunction. This class contains the method FunctionHandlerAsync which is the actual Lambda function entry point. On AWS, Lambda handler should be set to
AWSApiGatewayWithLambda::AWSApiGatewayWithLambda.LambdaEntryPoint::FunctionHandlerAsync. To do that, a NuGet package Amazon.Lambda.AspNetCoreServer is required. So, I add the package and create the LambdaEntryPoint class

using Microsoft.AspNetCore.Hosting; 
namespace AWSApiGatewayWithLambda {
    public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction {
        protected override void Init(IWebHostBuilder builder) => builder.UseStartup();
    }
}

AFAIK, there is only one class can be marked as lambda function in an assembly. There are some other restrictions with a lambda function. The default concurrency limit across all aws lambda functions per region in a given account is 1,000. Please find out more about the Limitations of AWS Lambda here.

I have added the pacakage Microsoft.AspNetCore.App and remove Microsoft.AspNetCore.All

Let’s move to Startup. Now the Startup class looks like

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Mvc;
 
namespace AWSApiGatewayWithLambda {
    public class Startup {
        public void ConfigureServices(IServiceCollection services) {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            }
            app.UseMvc();
        }
    }
}

Now, I am going to add a controller. Can you guess what will be my controller name? Yes, it is the ValuesController

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
 
namespace AWSApiGatewayWithLambda {
    [Route("api/[controller]")]
    public class ValuesController : Controller {
 
        private readonly ILogger _logger;
        public ValuesController(ILogger logger)
        {
            _logger = logger;
        }
 
        // GET api/values
        [HttpGet]
        public IEnumerable Get() {
            return new string[] { "value1", "value2" };
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id) {
            return "value";
        }
 
        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value) {
            _logger.LogInformation($"Post Value {value}");
        }
    }
}

Now, I’ll create publish and create the zip file to upload as AWS lambda. To check how to do that you can check this post here.

To test the lambda lets create a test based on the API Gateway AWS Proxy. Change the path like below

....
"pathParameters": {
  "proxy": "api/values"
},
"httpMethod": "GET",
  "stageVariables": {
  "baz": "qux"
},
"path": "api/values"

The test should return 200 with values

API Gateway Setup

I will be editing the newly created AWS API Gateway from aws console. Let’s create a new api and I call this test.

Then from the action dropdown select Create Resource.

 

This opens the page below where a new proxy resource can be created

This brings the page where you set the lambda function to trigger from API Gateway

A confirmation window shows to add permission to lambda

The resource has been created

You can also test the api

Now you need to deploy Api to any stage to access it from the outside world. After the deployment completed, an url will be provided. you can put the URL on a browser and add /api/values to see the result on the page. And also, all the requests show write entries on CloudWatch

Takeaway

  1. Basically, only one package Amazon.Lambda.AspNetCoreServer is required to build a lambda which will be triggerws by API gateway. you may need other packages to deploy or to use other AWS services. Amazon.Lambda.Tools is required to create the deployment package
  2. An entry point is required for lambda which must be derived from Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
  3. This is easy to trigger lambda function from Api gateway which is configure as Proxy
  4. This could be used as a tool to build a reliable, scalable and cost effective API

And also, it is possible to manage concurrency of lambda to process a batch of events or for cost reasons or to match with a downstream resource; check AWS documentation here

1 thought on “Build an API Gateway with Lambda Function in dotnet Core”

I would like to hear your thoughts