Building an API with TypeScript, AWS Lambda and endpts

In this article, we will learn how to build and deploy a serverless API with AWS Lambda and TypeScript using the endpts platform.

There are a number of steps that go into deploying a TypeScript API to AWS Lambda:

  1. Transpiling the TypeScript code to JavaScript so that it can be executed by Lambda's Node.js runtime
  2. Minifying, bundling, and performing code-splitting on the transpiled code to generate an optimized bundle for Lambda
  3. Packaging and deploying the bundle and dependencies to AWS Lambda
  4. Wiring up the Lambda function to an API Gateway endpoint so that it can be invoked over HTTP

When it comes to automating the deployment and configuration of the Lambda and API Gateway, there are quite a few options to choose from. For example:

Introduction

We will build a simple API that generates QR codes. The API will have a single endpoint that accepts the contents of the code in the body and returns a QR that we can render in the terminal or browser. We will use the qrcode package to generate the QR.

Calling the deployed QR API

Setting up our project

First things first, let's go ahead and set up our project. Switch over to your terminal and let's bootstrap our endpts project:

npm create endpts@latest qr-api

This will create a new directory called qr-api, install the dependencies, configure TypeScript, and set up the local development server to allow you to test your changes locally without having to trigger a deployment each time.

Let's change into the project directory and install the qrcode package:

cd qr-api
npm install qrcode
npm install --save-dev @types/qrcode

Writing our function

Now that we have our project set up, we can create our route. Go ahead and create a new file called qr.ts in the routes directory with the following content:

// routes/qr.ts
import QRCode from 'qrcode'
import type { Route } from '@endpts/types'

export default {
  method: 'POST',
  path: '/qr',
  async handler(req) {
    const body = await req.text()

    if (!body) return new Response('No text provided', { status: 400 })

    return new Response(await QRCode.toString(body))
  },
} satisfies Route

This will create a new route that accepts a POST request to the /qr path. The handler will accept the request body and generate a QR code from it. If the request body is empty, we will return a 400 response.

Let's fire up the development server and test our function:

npm run dev

In a seperate terminal make a POST request to the /qr endpoint running locally:

curl -X POST -d "Hello World" http://localhost:3000/qr

We should see the following output:

Testing the QR API locally

Deploying our function

Now that we've tested out function locally and are sure it works as intended, let's deploy it!

If you haven't yet, create an account on the endpts Dashboard (there are no forms to fill or credit cards required).

Once you've created an account, you will see a screen that looks like this:

Create a project page on the endpts Dashboard

You can connect your GitHub account to automatically deploy your functions on every push or alternatively use the manual deployment method to provide the link to a repository that would automatically be deployed.

For this tutorial, we'll use the manual deployment method. Select the Manual Deployment option, give the project a name (e.g.: qr-api), and provide a repository URL that will be cloned and deployed (e.g.: https://github.com/endpts-samples/qr-api):

Manual deployment method

Hit the Deploy project button and in just a couple of minutes, the project will be built and deployed to AWS Lambda and you will recieve a unique deployment URL:

Deployment URLs

You can now test out your function by sending a POST request to the /qr endpoint:

curl -X POST -d "Hello World" https://acme-qr-api.endpts.dev/qr