Tomasz Tarnowski
Tomasz Tarnowski

Tomasz Tarnowski

Getting started with AWS Lambda and Serverless Framework

Getting started with AWS Lambda and Serverless Framework

Tomasz Tarnowski's photo
Tomasz Tarnowski
ยทJul 8, 2021ยท

7 min read

Featured on Hashnode

In this article, you're going to learn how to deploy your first AWS Lambda Function as an API Gateway endpoint without much of a hassle thanks to the Serverless Framework.

The technologies used in this tutorial:

  • Serverless Framework
  • AWS Lambda
  • AWS API Gateway
  • Node.js

What is Serverless?

Serverless is an on-demand service that allows for the execution of the code in the cloud.

The term itself might be a little bit confusing as it indicates that there are no servers being used which is not true. There are servers involved however you as a developer don't have to worry about how your code is going to be executed, all the server management is going to be handled by the provider company (AWS in our case).


What makes Serverless great?

  • Cost-effectiveness:
    • you pay only for the usage - number of requests + RAM of memory used per second
    • it's really cheap - in most of the regions, it's only 0.20$ per 1 Million requests plus $0.0000166667 for every GB-second

      for more information have a look at the official AWS Lambda pricing page: aws.amazon.com/lambda/pricing

  • Fast parallel execution: lambda functions are being executed in parallel whether it's just computing or an API it's all blazingly fast
  • Time-efficiency: time that you spend on managing infrastructure is reduced to the minimum
  • Scalability, security, logging, and monitoring - all included and handled by the provider

Prerequisites

There are few things that you need to handle yourself before we get started I added links below to the relevant resources.

All installed and ready? Let's get started, then.


Step 1. Install serverless framework globally with npm

In your command line run:

npm install -g serverless

Restart your command line:

For Linux:

exec bash -l

For Mac:

exec zsh -l

Or just close the terminal window and open it again.

Step 2. Create serverless project from the template

  1. Change the directory to the one where you would like your new serverless project to be created, for example:

    cd ~/Projects
    
  2. To create a new serverless project from the default template run:

    serverless create --template aws-nodejs --path my-lambda-function
    

    where "my-lambda-function" is the name of the folder where your project is going to be created.

  3. You can open a newly created project (my-lambda-function folder) with a code editor now.

  4. Open serverless.yml file.

Step 3. serverless.yml

The serverless.yml file stores all of our lambda configuration, here is how it's going to look like (I removed all the commented out code that is not relevant for this article):

# Welcome to Serverless!
# ...

service: my-lambda-function

# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
frameworkVersion: '2'

provider:
  name: aws
  runtime: nodejs12.x
  lambdaHashingVersion: 20201221

# you can overwrite defaults here
#  stage: dev
#  region: us-east-1

# ...

functions:
  hello:
    handler: handler.hello

Region

What we are interested in first is the region:

# you can overwrite defaults here
#  stage: dev
#  region: us-east-1

that should be based on where the consumers of your API are mainly based.

And if that region for you is different than us-east-1 just uncomment the relevant line and change the value. Here is how it looks like for me:

# you can overwrite defaults here
#  stage: dev
  region: eu-west-1

Function

Now let's turn the default lambda function into API Gateway endpoint.

Change this section:

functions:
  hello:
    handler: handler.hello

to this:

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

where:

  • hello is the function name
  • handler.hello points lambda to the handler.js file and exported hello function
  • events:
    - http:
        path: /hello
        method: get
    
    sets GET HTTP endpoint with API Gateway under:
    https://<API_GATEWAY_UNIQUE_URL>/hello
    

Summary

This is how your serverless.yml file should look like after the above modifications:

# Welcome to Serverless!
# ...

service: my-lambda-function

# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
frameworkVersion: '2'

provider:
  name: aws
  runtime: nodejs12.x
  lambdaHashingVersion: 20201221

# you can overwrite defaults here
#  stage: dev
region: eu-west-1

# ...

functions:
  exchange:
    handler: handler.hello
    events:
      - http:
          path: /hello
          method: get
# ...

For a full reference of serverless.yml go to Serverless Framework official documentation: serverless.com/framework/docs/providers/aws..

Step 4. handler.js

Lambda function code is located in handler.js. Default content of this file should be as follows:

'use strict';

module.exports.hello = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Go Serverless v1.0! Your function executed successfully!',
        input: event,
      },
      null,
      2
    ),
  };

  // ...
};

where we can distinguish:

  • module.exports.hello with hello being the name of the function
  • event argument containing all the request information - params, headers, body and extra info from API Gateway
  • return object with required statusCode and body properties - this is going to be the returned response

    Here is full lambda response interface that includes the headers and base64 option: github.com/DefinitelyTyped/DefinitelyTyped/..

There is no need to modify anything in the file, although to be a bit more original here I'm going to change the message and add one more property to the response body:

'use strict';

module.exports.hello = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        // changed message
        message: 'Hello from AWS Lambda!',
        // added statusCode
        statusCode: 200,
        input: event,
      },
      null,
      2
    ),
  };

  // ...
};

Now, we're ready to deploy.

Step 5. Deploy it.

In the terminal run the following command from your project directory:

serverless deploy

If your AWS CLI is configured correctly, after few minutes of waiting you should see the success message and URL to your newly created endpoint:

..............................
Serverless: Stack update finished...
Service Information
service: my-lambda-function
stage: dev
region: eu-west-1
stack: my-lambda-function-dev
resources: 11
api keys:
  None
endpoints:
  GET - https://qeb5mnc2ni.execute-api.eu-west-1.amazonaws.com/dev/hello
functions:
  hello: my-lambda-function-dev-hello
layers:
  None

**************************************************************************************************

The endpoint is located here:

...
endpoints:
  GET - https://qeb5mnc2ni.execute-api.eu-west-1.amazonaws.com/dev/hello
...

Step 6. Test it.

To check if your endpoint works correctly simply copy and paste the API Gateway endpoint URL to your browser:

Screenshot 2021-07-03 at 16.02.45.png

Screenshot 2021-07-03 at 16.03.18.png

Or from a command line run:

curl https://<API_GATEWAY_ENDPOINT_URL>

Successful output:

curl https://qeb5mnc2ni.execute-api.eu-west-1.amazonaws.com/dev/hello{  "message": "Hello from AWS Lambda!",  "statusCode": 200,
  "input": {
    "resource": "/hello",
    "path": "/hello",
    "httpMethod": "GET",
    "headers": {
      "Accept": "*/*",
      ...
    },
    "multiValueHeaders": {
      ...
    },
    "queryStringParameters": null,
    "multiValueQueryStringParameters": null,
    "pathParameters": null,
    "stageVariables": null,
    "requestContext": {
      "resourceId": "71129x",
      "resourcePath": "/hello",
      "httpMethod": "GET",
      "extendedRequestId": "B5hbPFgBDoEFjMQ=",
      "requestTime": "03/Jul/2021:15:03:35 +0000",
      "path": "/dev/hello",
      ...
      },
      "domainName": "qeb5mnc2ni.execute-api.eu-west-1.amazonaws.com",
      "apiId": "qeb5mnc2ni"
    },
    "body": null,
    "isBase64Encoded": false
  }
}%

Conclusion

Congratulations on getting to the end of my article ๐ŸŽ‰.

If you followed all the above steps it means you can now create and deploy an AWS Lambda Function as an API Gateway Endpoint!

Try to do some experiments. You can for example change hello function code to include headers in the response. Whenever you make any changes just deploy Lambda again by running serverless deploy.


GitHub repository with all the code from this article:


If you liked this post and you're looking for more give me a follow on Twitter ๐Ÿฆ so you'll stay up to date with all the future content I create.


This post has an informative manner I don't receive any commissions from services promoted here.

ย 
Share this