Restful webhook using Lambda + API Gateway— PART 1

Christopher Lagali
8 min readDec 27, 2020
Photo by ADITYA PRAKASH on Unsplash

Just last week when I was confident on knowing most of AWS Lambda’s Capabilities; my colleague threw me a new one. API!!!!

I metaphorically ran over to my desk (googled) to see if that was even possible. Turns out, yeah!

Well that was enough to throw my work out of the window and get into googling. 20 browser tabs and 3 face washes later he pings me the python package employed: flask-lambda. After an agony filled weekend I am proud to report; I got it!!!

This is for all those geeks out there who love to stitch light weight applications from Scratch and see a 200 return Code :D

The Bigger Picture:

As a part of a 3 part series I intend to guide you into building a web-hook using Lambda and API Gateway.

The Web-hook which is impersonated by a Lambda function will listen in on a URL (exposed by API Gateway) to which GitHub will post a response whenever an event occurs. In this case the trigger event is a push made to one of our repositories hosted on GitHub.

Here is what we will set to achieve:

Baby Steps:

In Part 1 we shall start with building the integration between API gateway and the Lambda. Postman will be used to test this code and see if we unravel any issues.

Lambda

Lambda essentially is a way to run your code on demand without paying or setting up any servers. So all the prerequisites that your code needs (apart from what is inbuilt) needs to be packaged with your code.

The packages we will be using are flask and flask-lambda.

Its a good idea to develop your code in a virtual environment and have all its packages installed in there. Makes your code cleaner and lighter.

To start with create a virtual environment:

> virtualenv — python=/usr/bin/python3.6 python36

After you have created a virtual environment; in this case named python36 you need to activate it.

> source python36/bin/activate

Notice the name of your virtual environment in the left most corner; which means you are now inside your environment.

Let the installation begin!

We start by installing flask-lambda using pip.

With flask-lambda installed you will not need to install Flask explicitly.

Lets now create the actual lambda code:

The code above is to not just say hello but is to send out a json object with some Transaction related information.

Now run this code to test it in your environment as flask-lambda will let you do so as if you were executing it on Lambda itself.

Once done; come out of the environment.

> deactivate

Lets start zipping your code and your dependencies. For this, head over to the location where flask-lambda package is installed. This would essentially be the python3.6 directory in your virtual environment base location.

In this case it will be:

cd python36/lib/python3.6/site-packages/

use the following to zip the contents of the folder:

zip -r /home/ec2-user/lambda/my-deployment-package.zip .

Now, move this zip folder to the folder where your lambda_function python code exists and add your lambda_function.py file to the zip.

The results of your zip should look something similar:

Zipping all dependency packages together with your code make its easier for the lambda function to load and execute them when referenced in your py code.

This is my resultant folder structure:

We were repackaging a missing dependency in the deployment package when this screenshot was taken.

Armed with the zipped contents; head over to the Lambda function in the AWS console and upload the code as a zip:

The zipped package might take a few minutes to upload based on its size.

Modifying Runtime Settings:

The Handler settings gives Lambda an idea as to which method it needs to execute once it is invoked. In our case lambda_function.app is suitable as this refers to our Flask application name.

Local Testing

Once done go ahead and test it by configuring a test event.

API Gateway test template will give you a skeleton of the test JSON object that will emulate a request if sent from an external API client.

Go ahead and add the url resource name you added in the Flak app. In this case it is /hello and httpMethod will be GET.

Save this Test Template and execute it.

The response Body seen here is the JSON object that was built and returned by your Flask app when it gets triggered.

Well!! With your business Logic in place its time to spruce up the front end.

Errors and Resolution:

Since we are packaging code; chances of missing a few dependencies is highly likely. This is evident by errors of this nature:

In such a situation try installing that package in the local folder and re add it to the deployment package manually.

pip install markupsafe -t ./zip -r my-deployment-package.zip markupsafe-1.1.dist-info/

After you have re packaged the code you will need to redeploy the zip folder and perform a test.

API Gateway

Lets give the code a face; enter API gateway.

Locate API Gateway from the AWS Console and choose to create a new REST API. Provide a suitable name and select Create API.

The wizard will then lead you to the place where you will spend 90% of your time while building APIs.

Here we will do the following:

  • Create a Resource — similar to the Route URL specified in the Lambda Function. (indicated by line 7 in git code)
  • Create a Method — The Method should coincide with the Method specified in the Lambda Function for the specific Resource. (indicated by line 7 in git code)

In this case we will provide hello as our Resource name.

and our method will be GET.

While creating the method; one is required to specify the target of this method invocation. Here it will be the Lambda Function we created earlier.

One aspect of API Gateway that I love is the summary window for each method; which gives the develop a clear idea of where the request is going to be redirected to.

To Test this we will first need to deploy the API.

From the Actions menu (located beside the Resources label) select Deploy API. In the Deployment window we shall create a new Stage named Test and select Deploy.

Note: The Stage name does appear in the resultant API URL.

As of this part your API is now live and a URL to invoke is provided in Invoke URL section.

Note: The tricky part here is the URL you need to use to Invoke your method.

In the Stages page we thus go all the way down to GET and use that URL to test our API. The reason for doing this is to extract the complete URL with the resource name in it.

Lets rush over to postman and see what we get!

Alright! we see a 200 Response code which is good!

Summary:

The response that we see in postman is a JSON object that was built in our Lambda Function’s get_Hello() method.

In a nut shell:

  • We sent a GET request to the /hello Resource of our API.
  • API Gateway then rerouted this request (made from Postman) to the specific Lambda function(as initialized while creating the Method for resource /hello).
  • The Lambda Function then mapped this request to the python function get_Hello() (using the wrapper @app.route() method) which responded with the JSON object.
  • This Resultant object then travels back to our Postman Client.

Congratulations! You created your first light weight API which I must admit doesn’t do much for now; but will look much cooler once we are done with it.

--

--

Christopher Lagali

An Enthusiastic Data Eng. who is on a mission to unravel the possibilities of pipeline building with AWS and who believes in knowledge sharing.