How To Create Serverless API Functions With AWS Lambda
Tags: serverless, aws, node, javascript
Published: 2019-05-21 14:31:18

In this tutorial, we will learn how to create the serverless API functions. We will be using the [serverless framework](https://serverless.com) and host the functions to AWS Lambda.

### Wondering why serverless?

Please check [AWS Lambda](https://aws.amazon.com/lambda/) or Cloudflare's [why use serverless](https://www.cloudflare.com/learning/serverless/why-use-serverless/).

## Get started

Install the `serverless` globally

```bash
npm install -g serverless
```

Check if it is installed by running `serverless -v` command on terminal

```bash
serverless -v
1.42.3
```

## Get the boilerplate

We will use the _aws-nodejs_ template to create our service, let say with the name `testing-one`.

```bash
sls create --template aws-nodejs --path testing-one
```

Where `sls` is a shortcut of `serverless`.

The default template will have `handler.js`. It contains a dummy function called `hello`. The business logic should go inside it. In the next step, we will deploy the same function to AWS Lambda.

Let's simplify the `hello` function and return the `message` as below:

```javascript
module.exports.hello = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: `Hi, there!`
      },
      null,
      2
    )
  };
};
```

## Deploy to AWS Lambda

For deploying the functions to AWS, we need to set up credentials in our machine.

If it is already set up in your machine, the below command should display the _access key id_ and _secret access key_

```bash
cat < ~/.aws/credentials

[default]
aws_access_key_id = your-access-key-id
aws_secret_access_key = your-secret-access-key
```

Else, please follow this [video](https://www.youtube.com/watch?v=KngM5bfpttA), to set up the AWS credentials.

To deploy the function, run the `deploy` command

```bash
sls deploy
```

If you navigate to the AWS Lambda console (https://console.aws.amazon.com > Services > Lambda > Function), you will find the `hello` function deployed there. (Make sure you have selected the correct region at top-right of the screen)

![lambda console](https://thepracticaldev.s3.amazonaws.com/i/53xuqhvqz8rald35do32.PNG)

The function name `testing-one-dev-hello` displayed is in the following format.

< service name > - < stage > - < function name >

## Invoke deployed function

```bash
sls invoke -f hello

{
 "statusCode": 200,
 "body": "{\n  \"message\": \"Hi, there!\"\n}"
}
```

where `-f` is shorthand of `-function`.

So the function `hello` is deployed and running. Let's make it a REST API function.

## Use the function as REST API

_Events_ are the things that trigger your functions to run. One of such kind of event is HTTP event. The HTTP event can be generated by one of the HTTP endpoints.

### Creating GET endpoint

Let say we want to trigger the `hello` function when a `GET` HTTP request made to the path `/hello`.

That is, `GET : https://someurl.com/hello`

The file `serverless.yml` is exactly for such kind of configuration in the serverless project.

> **YAML (.yml)** is a data-serialization language and used for configuration files. It's just like JSON but more human readable friendly.

In `serverless.yml`, change the `functions` sections as shown below.

> Please ensure you have proper [indentation as per YAML standards](https://www.tutorialspoint.com/yaml/yaml_basics.htm). You can also learn by playing at http://nodeca.github.io/js-yaml/

```yml
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
```

### Deploy the changes

```bash
sls deploy
```

The deploy command output should return you the URL endpoints that we should use to trigger the function.

![lambda GET endpoints](https://thepracticaldev.s3.amazonaws.com/i/gybrnub4sgwu6micu9up.png)

You can browse the endpoint in the browser. It will hit the lambda function and will return the below result.

```json
{
  "message": "Hi, there!"
}
```

### Accept Query String parameters

You can also pass the query string parameters and process it in your business logic.

Let's update the `hello` function to process the `name` parameter passed in as query string

```js
module.exports.hello = async event => {
  if (event.queryStringParameters && event.queryStringParameters.name) {
    return {
      statusCode: 200,
      body: JSON.stringify(
        {
          message: `Hi, ${event.queryStringParameters.name}!`
        },
        null,
        2
      )
    };
  }
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: `Hi, there!`
      },
      null,
      2
    )
  };
};
```

Now if you will hit the below URL, you should receive output as below

`https://some-random-text.execute-api.us-east-1.amazonaws.com/dev/hello?name=Sanket`

```json
{
  "message": "Hi, Sanket!"
}
```

### Creating POST endpoint

You can configure the function(let say `submitForm`) as POST in `serverless.yml` as below

```yml
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
  # POST endpoint
  submitForm:
    handler: handler.submitForm
    events:
      - http:
          path: submitForm
          method: post
```

The `submitForm` function will be
```js
module.exports.submitForm = async event => {
  if (event.body) {
    return {
      statusCode: 200,
      body: JSON.stringify(
        {
          data: JSON.parse(event.body)
        },
        null,
        2
      )
    };
  }

  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: "Received nothing"
      },
      null,
      2
    )
  };
};
```

Deploy the service using `sls deploy`

![lambda POST endpoints](https://thepracticaldev.s3.amazonaws.com/i/s1z6toi0nxey2vxmbhkj.png)


You can POST the data to the endpoint using tools like [Postman](https://www.getpostman.com/). It should respond with the data sent in the body.

![postman](https://thepracticaldev.s3.amazonaws.com/i/fiajnayofdp4ev0j84qu.png)

That's it for now. I hope you find the tutorial helpful to get started using the serverless functions. 


You can find the code explained here at https://github.com/3sanket3/serverless-aws-api-gateway