Develop and deploy a Fastify Serverless application on AWS 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
- 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:
- 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
- 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.
- Now, proceed by copying the
samconfig.toml
andtemplate.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.
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.