Write Your First Serverless Application With AWS
8 min read

Write Your First Serverless Application With AWS

A hands-on guide to setting up your first serverless application.

Serverless applications are gaining popularity lately. Let's go through the basics and learn to setup your own serverless application within minutes.

Photo by Christina @ wocintechchat.com / Unsplash

In this guide we will look at the core concepts of serverless applications and build one using AWS Lambda. This guide will not teach you how to program, or how to write SQL, instead it focuses solely on teaching you how to use and write serverless applications to your benefit.

Note, this guide will require an AWS account for setting up a serverless lambda.

What is a Serverless Application?

How can my code run without a server? While we call it serverless, it's not entirely serverless. Serverless means, your application's code is set up to be called at a point in time, and it will only run until it has completed. For AWS, you pay for each millisecond of processing time.

So does it not run on a server? Well, it does technically run on an infrastructure set up by your cloud provider, for example, AWS. They have an infrastructure set up, and whenever you call your application's endpoint, AWS will fetch your code and run it on their server. Once it has completed, the execution stops.

You will also find serverless applications to be called FaaS, Function as a Service, because with serverless applications, you manage functions instead of servers.

Why Go Serverless?

There are multiple reasons why one would want to follow the serverless route. First of all, smaller sized application libraries are easier to maintain, and even faster to ship. There are less dependencies and developers do not need to be as afraid of breaking existing functionalities.

Since you do not need to manage the infrastructure and servers, you do not need to worry about scaling, the cloud provider will handle this.

A per millisecond billing granularity makes it perfect for those applications which are not used frequently. With about 3 million calls, you would only pay about $18. If your application has very low traffic, then this would be much cheaper than renting a server. Furthermore, this billing granularity motivates development teams to produce even faster code, because admit it – slow applications should be part of the past.

Serverless is also seen as a trend. Unfortunately, this is not a valid reason for going serverless. If you'd like to learn to write serverless applications, play around with them in spare time small projects, but do make architectural decisions wisely!

In the below screen from Google Trends, we can see how AWS Serverless Lambdas have gradually become evenly or even more popular than Amazon's EC2 server instances.

AWS Lambda vs. AWS EC2; Google Trends

Why Not Always Use Serverless?

Serverless applications also have clear downsides. For one, the application can only be run on execution. This means, serverless applications cannot be used for running listeners which are required to be turned on 24/7. Serverless applications are more used for short-living one-off requests.

Cold starts is an important concept in the serverless architecture. This is the time it takes for your cloud provider to retrieve your application's code, and start loading and running it in a separate execution environment. Cold start times can vary depending on the cloud provider you are choosing.

One way to solve cold starts, is to keep your lambdas warm. This means that your cloud provider will keep your serverless application ready for execution, dramatically reducing the time of the cold starts. However, keeping lambdas warm for long periods, one might wonder why not choose a server architecture instead. If  cold starts are an issue for your use case, then a serverless application might not be the best fit in your architecture.

Setting Up Lambdas

Let's set up your first lambda! First of all go to the Lambda section in the AWS Console.

Create a serverless function.

Leave the settings as is, and choose a name for your first lambda. We will keep the runtime as Node.js, to write a simple serverless application.

You will see the following screen with all the settings regarding your newly created lambda. Let's keep the hello world function as default for now and try it out.

Click on the test tab, keep thee settings as is and select Invoke.

Once done, you will see the response from your lambda appear.

That was your first lambda! Now let's try something a bit more fun! Let's create a service which returns a random joke every time. We will use an npm package called awesome-dev-jokes for this purpose.

Let's setup a package.json with a dependency for the awesome-dev-jokes package. Select the code tab in your AWS lambda, and create the package.json file with the following contents.

{
  "name": "my-first-lambda",
  "description": "",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
      "awesome-dev-jokes": "^1.0.3"
  }
}

Then, let's tune up our actual service. Update index.js to use the awesome-dev-jokes package and return a joke as a response in JSON format.

// Import the awesome-dev-jokes package
const awesomeDevJokes = require('awesome-dev-jokes');

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: {
            // Return an awesome dev joke
            joke: awesomeDevJokes.getRandomJoke()
        },
    };
    return response;
};

Once done, save your files and press the orange deploy button.

Test the lambda once again and take a look at the result.

The execution failed, since the awesome-dev-jokes package could not be found. Why would this be? Well, AWS doesn't build applications for you. You will have to submit your full code to AWS, including any third-party packages. A quick solution to this is to install it locally, zip your source folder and uploading it with the upload button next to the orange deploy.

However, many IDEs have integrated solutions for automatically deploying to lambdas. Let's set this up in Visual Studio Code.

Deploying Lambdas With Visual Studio Code

First, install the AWS Toolkit extension for Visual Studio Code. This extension will add a button on the left sidebar with functionalities such as uploading code to an AWS Lambda.

Once done, enter your AWS access key and secret access keys. Optionally, you could create an account in IAM with specific access for the lambda. Let me know in the comments if you would be interested in a tutorial regarding IAM.

Let's get back to our project – load the index.js and package.json into Visual Studio Code and run npm install, the node_modules folder should appear.

In the AWS toolkit, connect to your account, select your lambda's region, in my case this was eu-west-1. Expand the Lambda section, right click on your lambda and upload it to AWS.

Upload a lambda using the AWS Toolkit in Visual Studio Code

Let's head back to the AWS console to test our lambda! Invoke the lambda and enjoy the awesome dev joke that comes out of it. Another way to invoke your lambda would be to right click on it using the AWS toolkit in Visual Studio Code, then select invoke. This will trigger the lambda in your terminal. Try it to see which method you prefer.

If only we had the source code of the world!

Invoking a Lambda Locally

We've got our first lambda running and it is already throwing awesome dev jokes at us, great job! What about local development? Let's try to run our lambda locally and see what happens.

my-first-lambda $ node index
my-first-lambda $ 

There is no output. If we take a quick look at index.js, we should be able to understand why.

// Import the awesome-dev-jokes package
const awesomeDevJokes = require('awesome-dev-jokes');

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: {
            // Return an awesome dev joke
            joke: awesomeDevJokes.getRandomJoke()
        },
    };
    return response;
};

We are exporting a handler, which is an async function. However, when running node, this function will only be defined and not called. In order to run it locally, we can use the AWS SAM command line tool.

Follow the instructions from Amazon for installing the AWS SAM CLI tool. Next, you will also need to make sure Docker is installed on your machine, as this is a requirement from AWS.

Once installed, we can invoke the lambda using the following command.

$ sam local invoke
template.yaml is not defined

As we can see, we are missing the template.yaml file. For the sake of this tutorial, we could retrieve it from AWS. Go to your lambda in the AWS console and click on export.

Select the download AWS SAM file button, and copy the contents of this file towards ./template.yaml.

Let's run the lambda locally again using the sam local invoke command.

$ sam local invoke
Invoking index.handler (nodejs14.x)
Image was not found.
Building image.........
Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-nodejs14.x:rapid-1.17.0.

START RequestId: e3958938-8c70-477f-b2bd-e8bcc633452b Version: $LATEST
END RequestId: e3958938-8c70-477f-b2bd-e8bcc633452b
REPORT RequestId: e3958938-8c70-477f-b2bd-e8bcc633452b  Init Duration: 1.04 ms  Duration: 708.70 ms     Billed Duration: 800 ms Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode":200,"body":{"joke":"A programmer puts two glasses on his bedside table before going to sleep. A full one, in case he gets thirsty, and an empty one, in case he doesn’t."}}   

And there we have our final result! If you wish to run breakpoints, we can use the flag --debug-port 5858 to select a debug port. Configure this debug port in your IDE to make this work. Amazon has a sample launch configuration for Visual Studio Code available on their documentation website.

Summary

Serverless functions can be useful for fast development, less complex maintenance and the cloud provider takes the effort of maintaining stable servers and scaling out of your hands.

In some cases, the serverless approach is not recommended. For example, when the fastest speed is mandatory and cold starts cannot be tolerated. For some applications, serverless applications are not possible, for example 24/7 listeners, where callbacks are not possible.

In this article we have learnt how serverless technology works, and how to develop with it on AWS. In an enterprise environment, you will however not get this amount of access. A solution for this would be to use CloudFormation templates.

Please note, I am not affiliated with AWS, I simply love the services they offer.