⏱ 10 Minute Tutorial: Creating a Serverless Express Web Server & API
Tags: node, javascript, serverless, aws
Published: 2020-01-05 16:13:23

---
title: ⏱ 10 Minute Tutorial: Creating a Serverless Express Web Server & API
published: true
description: How to create and deploy a serverless Express web server with an HTTP API and routing using AWS Lambda.
tags: nodejs, javascript, serverless, aws
cover_image: https://thepracticaldev.s3.amazonaws.com/i/2t45ymt1o4ehgydglo9c.jpg
---

One of the most popular use cases of serverless functions is deploying and running a web server complete with routing. In this tutorial, I'll show you how to get this up and running in only a few minutes using [AWS Lambda](https://aws.amazon.com/lambda/), [Amazon API Gateway](https://aws.amazon.com/api-gateway/), and [AWS Amplify](https://aws-amplify.github.io/).

The library I'll be using is the [Serverless Express](https://github.com/awslabs/aws-serverless-express) project that's made specifically for this use case.

Using this library, you can easily proxy the `event` and `context` into the [express](https://expressjs.com/) server, and from there you'll have access to the different routes and HTTP methods like `get`, `post`, `put`, and `delete`.

```js
app.get('/', (req, res) => {
  res.json(req.apiGateway.event)
})
```

## Getting started

There are many ways to deploy a Lambda function, you can go directly into the AWS console, use the serverless framework, or a multitude of other tools that utilize infrastructure as code under the hood.

I will be using a CLI based approach with the [Amplify Framework](https://aws-amplify.github.io/).

To get started, first install and configure the Amplify CLI. 

> To see a video walkthrough of how to configure the CLI, click [here](https://www.youtube.com/watch?v=fWbM5DLh25U).

```sh
$ npm install -g @aws-amplify/cli

$ amplify configure
```

Now, create a project using your JavaScript framework of choice (React, Angular, Vue etc..).

```sh
$ npx create-react-app myapp

$ cd myapp

$ npm install aws-amplify
```

Next, initialize a new Amplify project in the root of your JS project:

```sh
$ amplify init

# Answer the questions prompted by the CLI
```

Now, we can create the API and web server. To do so, we can use the Amplify `add` command:

```sh
$ amplify add api

? Please select from one of the below mentioned services: REST
? Provide a friendly name for your resource to be used as a label for this category in the project: myapi
? Provide a path (e.g., /items): /items (or whatever path you would like)
? Choose a Lambda source: Create a new Lambda function
? Provide a friendly name for your resource to be used as a label for this category in the project: mylambda
? Provide the AWS Lambda function name: mylambda
? Choose the function template that you want to use: Serverless express function
? Do you want to access other resources created in this project from your Lambda function? N
? Do you want to edit the local lambda function now? N
? Restrict API access: N
? Do you want to add another path? N
```

The CLI has created a few things for us:

- API endpoint
- Lambda function
- Web server using Serverless Express in the function
- Some boilerplate code for different methods on the `/items` route

Let's open the code for the server. 

Open __amplify/backend/function/mylambda/src/index.js__. Here, you will see the main function handler with the `event` and `context` being proxied to an express server located at `./app.js`:

```js
const awsServerlessExpress = require('aws-serverless-express');
const app = require('./app');

const server = awsServerlessExpress.createServer(app);

exports.handler = (event, context) => {
  console.log(`EVENT: ${JSON.stringify(event)}`);
  awsServerlessExpress.proxy(server, event, context);
};

```

Next, open __amplify/backend/function/mylambda/src/app.js__.

Here, you will see the code for the express server and some boilerplate for the different HTTP methods for the route we declared. Find the route for `app.get('/items')` and update it to the following:

```js
// amplify/backend/function/mylambda/src/app.js
app.get('/items', function(req, res) {
  const items = ['hello', 'world']
  res.json({ success: 'get call succeed!', items });
});
```

We can test it locally before deploying it, but we first need to install the dependencies for the Lambda:

```sh
$ cd amplify/backend/function/mylambda/src && npm install && cd ../../../../../
```

To invoke the function and start the server, run the following command:

```sh
$ amplify function invoke mylambda
```

Now, the server is running on port __3000__ and we can make requests against it. To do this from the command line, we can run this curl command:

```sh
$ curl http://localhost:3000/items

# {"success":"get call succeed!","items":["hello","world"]}%
```


To deploy the API and function, we can run the `push` command:

```sh
$ amplify push
```

Now, from any JS client, you can start interacting with the API:


```js
// get request
const items = await API.get('myapi', '/items')

// post with data
const data = { body: { items: ['some', 'new', 'items'] } }
await API.post('myapi', '/items', data)
```

From here, you may want to add additional path. To do so, run the update command:

```sh
$ amplify update api
```

From there, you can add, update, or remove paths.

For more info on the API category, click [here](https://docs.amplify.aws/lib/restapi/getting-started/).