Develop and deploy a Fastify Serverless application on AWS Lambda

fastify lambda

Learn by example! Explore AWS Lambda and Fastify integration through practical use cases and code samples.


Fastify, an avant-garde web framework, ingeniously marries an unparalleled developer experience with a lean overhead, bolstered by its robust plugin architecture. Taking cues from Hapi and Express, it takes its place among the fleetest web frameworks in existence.

Fastify extends its prowess into the universe of serverless REST APIs, such as AWS Lambda and AWS API Gateway. This journey is empowered by its expansive plugin ecosystem, fostering compatibility across a spectrum of cloud providers. Amid the bouquet of merits that Fastify offers serverless environments, none outshines its remarkable developmental simplicity. In your local domain, the Fastify application operates effortlessly, unburdened by supplementary tools. This very code, in seamless transition, metamorphoses into your chosen serverless realm, demanding merely an extra code snippet for execution.

The AWS Lambda Fastify plugin, an officially supported Fastify plugin, orchestrates the seamless construction of serverless web applications, services, and RESTful APIs, all leveraging Fastify atop AWS Lambda and Amazon API Gateway. An exquisite balance of power and efficiency, the @fastify/aws-lambda package weighs in at a mere 3.9 kB in its minified form and a featherlight 1.4 kB in compressed GZIP, contributing to the optimization of the AWS Lambda package size.

Setting Up Fastify and AWS Lambda Development Environment

The blog is written based on the following versions,

  • Fastify CLI: 5.8.0
  • Fastify: 4.2.2
  • @fastify/aws-lambda : 3.3.0
  • AWS SAM: 1.96.0
  • Node: 18
  1. Begin by installing the Fastify CLI using the command npm install fastify-cli. Create a new Fastify project using the Fastify CLI with the following command:
fastify generate . --esm

This command will generate an ESM-based JavaScript scaffold app for Fastify, organized within the folder structure depicted below: Fastify Init process

  1. To transform this solution into an AWS Lambda-powered application, install the @fastify/aws-lambda package using the following command:
npm install @fastify/aws-lambda --save
  1. With the Fastify AWS Lambda package initialized, execute the AWS SAM initialization command:
sam init

During initialization, select the template option labeled 3 - Serverless API for the Lambda and API Gateway combination. Afterward, specify the runtime as nodejs18.x. Enable the X-ray option and set Cloudwatch insight to No. Following these steps, provide a name for the project. This process will generate a new folder containing all SAM configurations and a sample project.

  1. Now, proceed by copying the samconfig.toml and template.yaml files to the parent folder where the Fastify code resides. Subsequently, delete the AWS SAM sample project. With these initial steps completed, you are now poised to commence local development.

Building a Fastify Application using AWS Lambda Fastify Plugin

To proceed in transforming this application into an AWS Lambda-powered system, the next imperative step is crafting a lambda handler file. Within this file, the focal point is the handler method. The handler function assumes the pivotal role of enveloping the Fastify app. It accomplishes this through the utilization of the awsLambdaFastify function, which is conveniently exposed by the @fastify/aws-lambda package. This function yields a proxy, which effectively serves as an intermediary linking the Fastify app and AWS Lambda.

Create a fresh file within the project directory and christen it as lambda.js. Below lies the code snippet to be seamlessly copied and pasted into this newly minted file.

import fastify from "fastify";
import app from "./app.js";
import awsLambdaFastify from "@fastify/aws-lambda";
const server = fastify({
  logger: true,
});
server.register(app);
export const handler = awsLambdaFastify(server);
await server.ready();

Moving forward, our focus is on delineating the routes within the designated routes folder. Within this project, two distinct routes are outlined: firstly, a GET endpoint bearing the URL /order, and secondly, a POST endpoint characterized by the URL /order.

To accomplish this, we embark on the creation of a fresh file within the routes directory. The chosen nomenclature for this file is order.js. It's worth noting that Fastify effortlessly automates the loading of the routes folder within the project, as it is explicitly passed in the app.js file.

Within order.js, the routes themselves take form, complete with the underlying code, schemas, and route methods. This meticulous structuring encapsulates the essence of our AWS Lambda Fastify example and the utilization of Fastify Lambda routes.

export default async function (fastify, opts) {
  fastify.route({
    method: "GET",
    url: "/order",
    handler: async (req, res) => {
      return {
        orderId: "123",
        products: [
          {
            productId: "1",
            productName: "T shirt",
            quantity: 2,
            rate: 100,
          },
        ],
      };
    },
  });
  fastify.route({
    method: "POST",
    url: "/order",
    schema: {
      body: {
        type: "object",
        // array of required fiels
        required: ["name", "products", "address"],
        properties: {
          name: { type: "string" },
          products: { type: "array" },
          address: { type: "object" },
        },
      },
      response: {
        201: {
          type: "object",
          properties: {
            orderId: { type: "string" },
          },
        },
      },
    },
    handler: async (req, res) => {
      const timestamp = Date.now();
      const randomPortion = Math.floor(Math.random() * 10000); // You can adjust the range as needed
      const uniqueIdentifier = `${timestamp}-${randomPortion}`;
      res.status(201);
      return { orderId: uniqueIdentifier };
    },
  });
}

Integrating AWS Lambda with Fastify using AWS SAM

With our code primed and ready, the next pivotal step entails modifications to the AWS SAM template.yaml configuration file. Herein, we incorporate vital lambda specifics, encompassing the handler method and paths. In this exemplar project, we orchestrate the deployment of two distinct lambdas - one tailored for the GET API endpoint /order and the other meticulously configured for the POST API endpoint /order.

Within the Resources section of the configuration, we discern the distinct lambdas, denominated as getOrderDetails and postOrder. The handler function designated for both these lambdas is aptly named lambda.handler. This handler function seamlessly aligns with the handler method contained within the lambda.js file. The updated template.yaml now boasts the following essential information:

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  fastify-sam-lambda
Transform:
- AWS::Serverless-2016-10-31
Resources:
  getOrderDetails:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda.handler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
      MemorySize: 128
      Timeout: 100
      Description: A simple get api end point hosted with Lambda + API Gateway integration using Fastify
      Events:
        Api:
          Type: Api
          Properties:
            Path: /order
            Method: GET
  postOrder:
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda.handler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
      MemorySize: 128
      Timeout: 100
      Description: A simple example includes a HTTP post method
      Events:
        Api:
          Type: Api
          Properties:
            Path: /order
            Method: POST
Outputs:
  WebEndpoint:
    Description: "API Gateway endpoint URL for Prod stage"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"

Local Testing and Debugging

In order to test Fastify AWS Lambda code locally, we are leveraging the AWS SAM cli commands. First we are building the entire solution with sam command : sam build. Incase the build is successful, it should create a .aws-sam folder and structure the entire code inside this folder.

Now we can run the command sam local start-api which will bring up the local solution in an emulated lambda environment using container and also expose end points through localhost.

fastify lambda running locally The api end points can be tested using the postman or other rest api client. This ensures teh fastify lambda solution is running as local AWS Lambda and serve the response.

Deploy Fastify AWS Lambda Serverless Application using AWS SAM

Once the local testing is completed, the next step is to deploy fastify lambda using the AWS SAM. We will use sam deploy --guided --profile profile-name to deploy the changes to AWS Account. SAM will take care of automatically packaging the AWS fastify lambdas and deploy it to the AWS account depending on the profile name passed in the command.

Once the deployment is completed, deployment command should return the aws api gateway end point which we can use it test and integrate with other application.

Sample Repo for fastify app on AWS Lambda

The entire code base for this fastify aws lambda app is available in the Github.