AWS : Using Lambdas for Simple APIs

Introduction

AWS Lambda has always piqued my interest... The idea of writing and uploading a snippet of code that can then be invoked from numerous places within the AWS ecosystem is just so elegant. And it enables so many different kinds of behavior.

What makes Lambda really useful in my opinion however, is the synergy it has with the AWS API Gateway.

The API Gateway is a managed service for creating one or more URLs (called endpoints), each of which that can be implemented by different AWS services. Everything from an HTTP service, to an S3 bucket, to an AWS Lambda function.

Its the AWS Lambda function that is the interesting case!

Usually when you want to execute business logic on the server side, you have to develop a complete web application, provision an instance, and deploy a full web stack. In cases where the business logic is relatively simple, this can be overkill (even though technologies like AWS Elastic BeanStalk make it easier.)

Enter AWS Lambda. You can write your simple business logic as an AWS Lambda function, even integrating it into other back end services like DynamoDB or S3, and point an API Gateway endpoint at it.

Voila! You have, essentially, an extremely simple web server that provides dynamic business logic without the overhead of provisioning a web stack!

This realization dawned on me as I was playing around with AWS Lambda, so I wanted to show a simple example.

I have a scratch pad website hosted on GitHub Pages (www.marlthehammer.com). I decided to create a "quote of the day" link for that page. Something dirt simple but that would still demonstrate dynamic behavior.

Let me show you what I did!

AWS Lambda

Lambda can support code written in Python, NodeJS, and Java (at the moment.)

To create a function you go to "AWS Lambda" from the Console and select the "Create a Lambda function" button (or "Get Started" if the prompt is there).

The first screen you see prompts you to select a blueprint. Blueprints are just pre-written Lambdas for various purposes that have boilerplate code already provided. For example, there is a blueprint for a Lambda that retrieves data from DynamoDB. It provides all the boilerplate code to access DynamoDB, leaving the schema details and return format for you to fill in.

For my purposes I just clicked "Skip" but in the future you might choose to build a function from a blueprint to save time.

The next screen is where you define a "trigger" to activate your Lambda. In my case, we will wire up the Lambda function to the API Gateway, so no other trigger is needed. Again, I just clicked the "Next" button.

Finally you see a place to enter the Lambda definition! You enter a name and description and choose a runtime for your function. Then, in the space provided, you supply the source code.

The source code for my quote of the day function was very simple and is as follows:

import random

def lambda_handler(event, context):

    quotes = [
        'Know what you know. And know what you don't know.',
        'You have to know why things work the way they do, not just how they work.',
        'Now is the perfect time to panic!',
        'Needless consistency is the hobgoblin of small minds.',
        'I will give you a mile, but you are not going to take an inch.'
    ]

    return random.choice(quotes)

Just a simple Python function that returns a random string from the array.

After you enter your code, you can set additional permissions and parameters for the function. For Lambda functions that are going to access other parts of your infrastructure, you will need to give them a role with the appropriate permissions.

If you are satisfied, you click the "Next" button, review what you have entered, and create your Lambda function!

API Gateway

Hurray! That was step one. We have a Lambda function. At the moment though, there is no way to actually invoke that function. Next we consider the API Gateway.

To get started, go to "API Gateway" from the Console, and click the "Create API" button (or Get Started if the prompt is there). In the Create API screen you want to select New API in the radio group across the top. Give your API a Name and Description.

You are then taken to the API editor. This is a bit complicated, but makes sense once you do it a few times.

You can create two things of interest: Resources and Methods. A Resource corresponds to a unique URL path. A Method is a specific HTTP action performed on that URL and has an underlying implementation you specify.

In our case, we will create a /quote Resource by click Actions -> Create Resource. Give it a name of "Quote" and a path of /quote.

Next we need to create a means of reaching this resource, or in other words, a Method. Click Actions -> Create Method. The new method will be added to the tree structure on the left. You can select which HTTP action will invoke the Method (GET in our case).

You then get to specify the implementation of the method. In our case we will select "Lambda function", then select the Region where our function resides, and enter the function name (there is auto complete to help you!)

Finally you click Actions -> Deploy API to make your API available to the public. Congratulations! You have created and implemented an API!

If you click on the Dashboard link on the left you will see the base URL for the API at the top of the dashboard.

As an example, my base URL is: https://exztwhuso1.execute-api.us-west-2.amazonaws.com/test/. To invoke my particular Lambda, you use this url: https://exztwhuso1.execute-api.us-west-2.amazonaws.com/test/quote.

Conclusion

That is all there is to it! You can now create full fledged web applications by stringing AWS Lambda functions together with a set of API Gateway Resources! Very lightweight and very powerful.

Questions? Comments? Email me at [email protected]!