Consider this ordinary JavaScript function:

const sayHello = () => {
  return { message: 'hello' };
};

What if you wanted to put this function in the cloud for anyone on the internet to invoke? How might we go about it?

A complicated but common route would be to fire up a small instance on a cloud hosting provider, install a Linux flavoured OS, configure ports, install and configure a web-server, and so on. Finally we’d upload the function served by a basic node.js server. And each month we’d pay a fixed fee for the server instance, whether our function was invoked or not.

What if sayHello suddenly experiences a surge in traffic, crashing our small instance. We now have to set up a load balancer and fire up and configure new instances to handle the surge. And when the surge passes, we’d have to terminate those instances else face a hefty bill at the end of the month.

Magic Function Service in the Cloud

AWS Lambda is a service that can free us to think only about the function and how it interacts with its world - we can forget about everything else.

Nor must we endure sleepless nights worrying about paying for code that isn’t being used - with Lambda, we don’t pay for idle functions! And if our function should experience a traffic surge, it’ll rise to the challenge, meeting the new demand with no effort on our part.

What follows is a short story about a small function called sayHello. But to help write this story I’m going to use a small framework called Serverless - it’s a toolkit that’ll help keep the story brief.

To follow along, you’ll need to install and configure the Serverless Framework and have a free account setup with AWS.

A Function’s Beginnings

On the command line:

mkdir hello-world
cd hello-world
touch function.js

Let’s open up function.js so we can write our function. It’ll look a little different from our original above, but this is necessary for it to work with AWS Lambda:

module.exports.helloWorld = (event, context, callback) => {
  callback(null, { message: 'Hello World' });
};

Ignore the function’s signature - we’ll explore what event, context and callback are in another post.

Deployment

helloWorld will need an accompanying ‘map’ to show it the way to the cloud. That map is called serverless.yml, and contains the following:

service: helloWorldService

provider:
  name: aws
  runtime: nodejs6.10
  region: us-east-1

functions:
  helloWorld:
    handler: function.helloWorld

Written in yaml, the file declares a name for our service - helloWorldService. Think of a service as being like a project. It’s where we describe our functions, events that trigger them and any other AWS infrastructure we might need. AWS Lambda requires a runtime to be declared along with a region - we’re going to use us-east-1 (AWS supports Lambda across all of its regions). Finally, under functions we name our function, helloWorld. We also define the location of our function - function.helloWorld. function is the name of the file, and helloWorld is the name of the exported function.

Now helloWorld is ready for its journey. Just one command to send it on its way:

serverless deploy

You’ll see…

Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (225 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...............
Serverless: Stack update finished...
Service Information
service: helloWorldService
stage: dev
region: us-east-1
api keys:
  None
endpoints:
  None
functions:
  helloWorld: helloWorldService-dev-helloWorld

With our function now in the cloud, how can we reach it?

AWS allow functions to be invoked from the command line using their SDK. Serverless makes this easy:

serverless invoke --function helloWorld

What we get back as a response is the JSON object we passed to the function’s callback function:

{
    "message": "hello world"
}

Only being able to invoke the function from the command line isn’t that useful. AWS Lambda functions can respond to many other types of event. Let’s configure it to respond to an HTTP request. AWS has just the service for this - AWS API Gateway, and again, Serverless makes it dead easy to set this up:

# serverless.yml

service: helloWorldService

provider:
  name: aws
  runtime: nodejs6.10
  region: us-east-1

functions:
  helloWorld:
    handler: function.helloWorld
    events:
      - http:
          path: /hello
          method: get

We’ve added an HTTP event to our function in serverless.yml, and have declared a path and method.

Before we can deploy we need to update our function to have it respond nicely to an HTTP request:

module.exports.helloWorld = (event, context, callback) => {

  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: "Hello World",
    }),
  };

  callback(null, response);
};

The 200 status code indicates that the request has succeeded. Let’s deploy:

serverless deploy


# response
....................
Serverless: Stack update finished...
Service Information
service: helloWorldService
stage: dev
region: us-east-1
api keys:
  None
endpoints:
  GET - https://vxfkcc4buf.execute-api.us-east-2.amazonaws.com/dev/hello

functions:
  helloWorld: helloWorldService-dev-helloWorld

Notice now we get back from the deployment output an HTTP endpoint:

endpoints:
  GET - https://vxfkcc4buf.execute-api.us-east-1.amazonaws.com/dev/hello

If we paste the endpoint into a browser we’ll get back the hello world message! Lovely.

AWS Lambda is Event Driven

AWS has several, fully managed services, which can trigger Lambda functions. Examples include an S3 bucket calling a resize image Lambda function when a file has been uploaded, and a Lambda function that sends a new user a welcome email when their user record is first inserted into DynamoDB - a NoSQL database managed by AWS.

It’s a really exciting time to be a software developer. The bar for converting fine ideas into working software has dropped considerably with event driven, Lambda orientated applications and services. I hope you share my enthusiasm.