Fastify Fundamentals: Building Your First Route (2024)

Fastify is a robust framework for Node.js developers to build neat, secure, and scalable applications. It has internal infrastructure to help with logging, testing, and error handling.

In this blog, we will teach you how to use factories and plugins, and how to handle environment variables while building your applications.

By the end of this tutorial, you will have built your first Fastify route and should better understand how Fastify works.

How to Build Your First Route: Fastify Quickstart

Let’s start by building our first route.

Step 1: Install the Package

Create an app folder, initialize a Node project and install a Fastify package by running the below code in your terminal:

mkdir appcd appnpm init -ynpm i fastify

Step 2: Create a Server

Create a file named server.js and paste the code below into the file:

import fastify from 'fastify'const app = fastify()app.get('/', async (request, reply) => { return { hello: 'world' }})app.listen({ port: 3000 })

Step 3: Testing the Route

To test the route, run the curl command below in the terminal:

 curl http://localhost:3000

There is more to Fastify than the quickstart above– read on to discover more complex development actions you can implement.

Pino

Pino, the fastest logger for Node.js, provides the logging functionality for Fastify. Maintained by four collaborators, Pino boasts of 22 million average monthly downloads.

Below is a demo of how Pino works:

import pino from "pino";const logger = pino()logger.info('hello world')const child = logger.child({ a: 'property' })child.info('hello child!')// This Produces // // {"level":30,"time":1531171074631, "pid":77632, "hostname":"mcl", "msg":"hello world"}// {"level":30,"time":1531171082399, "pid":77632,"hostname":"mcl, "msg":"hello child!","a":"property", "msg":"hello child!"}

Pino makes it easy to create loggers and child loggers. It can be enabled in Fastify simply, as shown below:

import fastify from 'fastify'const app = fastify({ logger: true })app.get('/', async (request, reply) => { return { hello: 'world' }})app.listen({ port: 3000 })// This Produces // // {"level":30,"time":1531171074631, "pid":77301, "hostname":"mcl", "msg":"Server listening at http://[::1]:3000"}// {"level":30,"time":1531171082399, "pid":77301,"hostname":"mcl, "msg":"Server listening at http://127.0.0.0:3000"}

While this output is correct, it may be considered hard to read. An alternative is to use the pino-pretty package, which improves the log output.

To use pino-pretty, install the package by running the command in the terminal.

npm i pino-pretty
import fastify from 'fastify'const opts = { logger: true}// We want to use pino-pretty only if there is a human watching this,// otherwise, we log as newline-delimited JSON.if (process.stdout.isTTY) { opts.logger = { transport: { target: 'pino-pretty' } }}const app = fastify(opts)app.get('/', async (request, reply) => { return { hello: 'world' }})app.listen({ port: 3000 })

When the terminal is started, the output message is much more verbose. However, if a human does not read the logs in the terminal, they should be logged in JSON format.

Fastify Fundamentals: Building Your First Route (1)

The way Pino is set up makes it easy to handle the system's failure mode. The transport runs in a separate thread, making asynchronous processing easy even if the system crashes.

Notably, the @fastify/one-line-logger package is an alternative logger to Pino in the Fastify ecosystem. This is also an easy-to-use way to make logs more compact and can be integrated by replacing the target with @fastify/one-line-logger rather than pino-pretty.

Security By Default

An important feature of Fastify is its security.

By default, it only listens to the ports 127.0.0.1 and :1 (if both are available). However, it can be made available on all ports by setting the host option to 0.0.0.0. This is important if the app is to be run on cloud-based environments or Docker.

You can run Fastify with Docker by copying the code below and pasting it into your Docker file.

FROM node:18-alpine# Create app directoryWORKDIR /usr/src/app# Basic deps for Node.jsRUN apk update && apk add --no-cache dumb-init python3 libc-dev make g++# Install app dependenciesCOPY package*.json ./RUN npm ci --only=dev# Copy app source codeCOPY . .EXPOSE 3000ENTRYPOINT ["dumb-init"]CMD [ "node", "server-all-addresses.js" ]

Using Factories

It is not possible to write all the code in a single file. However, using factories allows further reusability and testing.

Let’s refactor the route. Start by creating a new file called app.js, then cut the get route from the server.js file and paste it into the app.js file. The app.js file looks like this:

Let’s refactor the route. Start by creating a new file called app.js, then cut the get route from the server.js file and paste it into the app.js file. The app.js file looks like this:import fastify from 'fastify'export async function build (opts = {}) { const app = fastify(opts) app.get('/', async (request, reply) => { return { hello: 'world' } }) return app}

Then, import the build function from the app.js and import and call it into the server.js file.

import { build } from './app.js'const opts = { logger: { level: 'info' }}// We want to use pino-pretty only if there is a human watching this,// otherwise we log as newline-delimited JSON.if (process.stdout.isTTY) { opts.logger.transport = { target: 'pino-pretty' }}const app = await build(opts)await app.listen({ port: 3000, host: '0.0.0.0' })

Testing

Testing is an important stage of application building. Although Fastify includes an embedded “inject” method for fast testing, we will use the node:assert and node:test modules to test our route.

import test from 'node:test'import {equal, deepEqual} from 'node:assert/strict'import { build } from './app.js'test('basic server', async (t) => { const app = await build() t.after(async () => { await app.close() }) const response = await app.inject({ method: 'GET', url: '/' }) equal(response.statusCode, 200) equal(response.headers['content-type'], 'application/json; charset=utf-8') deepEqual(response.json(), { hello: 'world' })})

The below result is obtained when the test is run.

Fastify Fundamentals: Building Your First Route (2)

Note that the content type for the JSON includes a charset. This is important, particularly if the app will be used in countries like China and Japan as it will affect the character output. Although a few frameworks remove this to save bytes, it is not good practice.

Shutting Down Processes

There are two ways of crashing an application. The first is to crash as badly as possible, while the second is to do a graceful shutdown.

Shutting down an application gracefully is required for business continuity. Fastify allows you to do so in a way that makes sense by stopping accepting new connections and working to close all outstanding keep-alive connections before exiting the process.

A graceful shutdown means the app keeps responding to as many requests as possible while breaking as few users as possible.

There is a special module to help achieve this: close-with-grace.

Run the command below to install the package:

npm i close-with-grace

Below is a demo of how to integrate the package with our Fastify application.

import { build } from './app.js'import closeWithGrace from 'close-with-grace'const opts = { logger: { level: 'info' }}// We want to use pino-pretty only if there is a human watching this,// otherwise we log as newline-delimited JSON.if (process.stdout.isTTY) { opts.logger.transport = { target: 'pino-pretty' }}const app = await build(opts)await app.listen({ port: 3000, host: '0.0.0.0' })closeWithGrace(async ({ signal, err }) => { if (err) { app.log.error({ err }, 'server closing due to error') } else { app.log.info(`${signal} received, server closing`) } await app.close()})

When the app starts and is closed by hitting CTRL + C button, the output below is logged to the terminal:

Fastify Fundamentals: Building Your First Route (3)

Close-with-grace has a couple of other options, including the delay option, which allows you to specify the time required for the application to shut down. The default delay is 10 seconds.

Adding .env Support

The best way to configure your application is by using a .env file. The .env file allows for local configuration and remote control.

Best practice entails never committing a .env file. Instead, a .env.sample file containing the sample of the secrets is what should be committed. A more strict implementation of this pattern is the env-schema.

Let’s look at a demo of how to load secrets from a .env file in our Fastify app.

First, install the dotenv package:

npm i dotenv

Create a .env file and paste the following keys and values.

HOST = 0.0.0.0PORT = 3042

Now in the server.js file import the .env file and initialize it at the top of the code as shown below:

import dotenv from "dotenv"dotenv.config()

Then edit the app and the listen method to include the secrets as shown below:

const port = process.env.PORT || 3000const host = process.env.HOST || '127.0.0.1'const app = await build(opts)await app.listen({ port, host })

It’s important to use the OR statement so that if a secret is missing, the application defaults to the other provided value. We wrote this blog to enhance your knowledge of handling environment variables.

Handling Errors

Error handling is another important aspect of development. It is important to handle errors appropriately to prevent the application from disclosing sensitive information.

To handle errors, use an error handler as shown below:

 app.get('/error', async (request, reply) => { throw new Error('kaboom') }) app.setErrorHandler(async (err, request, reply) => { request.log.error({ err }) reply.code(err.statusCode || 500) return {error: err.message} })

The handler logs the error and sets its status code to 500. Then it returns the error message. If a request is sent to the error URL, it returns the response given below:

Fastify Fundamentals: Building Your First Route (4)

Another error handler package that can be used is the @fastify/error package. To use it, install the package by running the command:

npm i @fastify/error

Import the package into the server.js file and create the error handler. Then call the error handler within the error route as shown below:

import createError from '@fastify/error'const KaboomError = createError('KaboomError', 'Something went Wrong', 501)app.get('/error', async (request, reply) => { throw new KaboomError() })

When a request is sent to the error route, the error below is obtained.

Fastify Fundamentals: Building Your First Route (5)

However, this will not work if you call the function within any operation that is outside the promise chain such as setTimeout.

Handle Not Found

The Not Found handler is automatically invoked when a route is not matched. It can also be manually set by invoking the ‘reply.callNotFound()’. Below is a demo of how to set the Not Found handler:

app.get('/notfound', async (request, reply) => { reply.callNotFound() })app.setNotFoundHandler(async (request, reply) => { reply.code(404) return "I'm sorry, I couldn't find what you were looking for." })

Thus, if the server is started and a request is sent to the notfound route, it returns the response shown below:

Fastify Fundamentals: Building Your First Route (6)

Plugins

You can refactor the routes declared in a route folder and register them as plugins in the app.js file.

For instance, we can create a new folder called route and a file called route.js, and paste the error route there as shown below. Then we can also add the first line to enable autocompletion on the app.

/** @type {import('fastify').FastifyPluginAsync<> } */ import createError from '@fastify/error'const KaboomError = createError('KaboomError', 'Something went Wrong', 501)export default function error (app, opts) { app.get('/error', async (request, reply) => { throw new KaboomError() });}

In the server file, the error route can be registered as a plugin as shown below:

import error from './routes/error.js';….//some code here....app.register(error);

Wrapping Up

In this article, we have seen an overview of Fastify’s core features, particularly its built-in infrastructure for logging and how it handles environment variables.

We also discussed the best practices Fastify provides for and supports, such as graceful shutdown processes. Notably, you have learned how to handle errors properly whenever you are building applications with Fastify.

Supercharging Fastify Development with Platformatic

Developed by the co-creator of Fastify, Platformatic is a backend development platform designed to extend the capabilities of the Fastify web framework. Together, Platformatic and Fastify offer:

  • Developer-centric design

  • Real-time metrics

  • A vast plugin ecosystem

  • Built-in validation and serialization

  • Built-in logging

Find out more and get in touch.

Fastify Fundamentals: Building Your First Route (2024)

FAQs

Fastify Fundamentals: Building Your First Route? ›

Fastify offers a compelling alternative to Express and other Node. js frameworks by focusing on performance, modern JavaScript features, and a robust plugin system. Its advantages make it particularly suitable for high-performance applications where efficiency and scalability are paramount.

Is fastify worth learning? ›

Fastify offers a compelling alternative to Express and other Node. js frameworks by focusing on performance, modern JavaScript features, and a robust plugin system. Its advantages make it particularly suitable for high-performance applications where efficiency and scalability are paramount.

What makes fastify faster than Express? ›

Fastify's lightweight architecture and efficient JSON parsing give it a performance edge. It uses an async/await model, allowing it to handle a large number of concurrent requests without blocking the event loop. Its HTTP router, 'find-my-way,' is significantly faster than Express's router.

Is fastify production ready? ›

GitHub - mehmetsefabalik/fastify-template: production-ready and development-friendly minimal Fastify Typescript Boilerplate, includes Mongoose, Jest for testing, Eslint for linting.

What is Fastify used for? ›

Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is inspired by Hapi and Express and as far as we know, it is one of the fastest web frameworks in town.

What are the disadvantages of fastify? ›

Disadvantages of Fastify

Being a relatively newer web framework, Fastify may have a smaller community compared to more established frameworks. This can result in limited availability of community-developed plugins, extensions, and community-driven support resources.

What companies are using fastify? ›

What companies use Fastify? Some of the companies that use Fastify include BrainFinance, AmeriSave, Hedra Consulting, Reydix GmbH, BizAway, Attestis, Peter Park System GmbH, LRQA - sustainability, Pipedrive, Grupo Boticário and many more. You can find a complete list of 761 companies that use Fastify on TheirStack.com.

Should I use NestJS or fastify? ›

Choosing between Fastify and NestJS depends largely on the specific needs of your project. Fastify excels in performance and simplicity, making it ideal for high-performance applications and those requiring fine-grained control over the architecture.

Will Fastify replace Express? ›

The Fastify-cli tool is particularly useful for quickly setting up a Fastify project, and it comes with several useful plugins pre-installed. But, of course, Express still has a more extensive collection of middleware and extensions at the moment.

What is the difference between fastify and Hapi? ›

Fastify uses a schema-based routing system, where routes are defined using JSON schemas. This allows for easy validation and serialization of request and response payloads. On the other hand, hapi uses a more traditional callback-based routing system, where routes are defined using JavaScript code.

Is koa better than Express? ›

Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. By leveraging async functions, Koa allows you to ditch callbacks and greatly increase error-handling.

What is the body size limit for fastify? ›

Body parser size limit

If your application needs to parse a body larger than the default 1MiB of Fastify, use the following: const bodyLimit = 10_485_760; // 10MiB app.

How to build a fastify project? ›

How to Build Your First Route: Fastify Quickstart
  1. Step 1: Install the Package. Create an app folder, initialize a Node project and install a Fastify package by running the below code in your terminal: ...
  2. Step 2: Create a Server. Create a file named server.js and paste the code below into the file: ...
  3. Step 3: Testing the Route.
Feb 13, 2024

Is Fastify worth it? ›

Some of the strongest points for fastify were: A comprehensive ecosystem, which includes a lot of high-quality, first-party plugins. We're building a system in production, which means things like rate limiting are going to be necessary, and it's amazing that fastify's rate limiter is well-architected.

What are the advantages of fastify over Express? ›

Fastify is optimized for performance and provides superior speed compared to other Node. js frameworks. It provides built-in support for features such as request validation, serialization, and deserialization, making it easy to build robust and secure applications.

Why is Fastify so fast? ›

Fastify provides full encapsulation for plug-ins, automatically parses JSON with relatively faster rendering, and provides quick routing. Among other benefits, Fastify also has a cleaner syntax for writing async code in controllers. Fastify is consistently faster than Express by 2–3 seconds.

What is the difference between fastify and Hyperexpress? ›

fastify: Fastify is designed to be extensible through its plugin system. This allows for modular development and easy integration of additional features and functionality. hyper-express: Hyper-Express is extensible through its middleware system, allowing developers to add custom functionality as needed.

Should I learn NestJS or Express? ›

Nestjs is designed to provide a structured and modular approach, making it easier to build and maintain large-scale applications, whereas Expressjs offers more flexibility but may require additional setup for scalability.

Top Articles
What Is Twitch Hardware Acceleration and How to Use It? - MiniTool
Zipping and Splitting Large Files
Poe T4 Aisling
Monthly Forecast Accuweather
Windcrest Little League Baseball
Ross Dress For Less Hiring Near Me
Apex Rank Leaderboard
Obituaries
Richard Sambade Obituary
Geometry Escape Challenge A Answer Key
DIN 41612 - FCI - PDF Catalogs | Technical Documentation
Lenscrafters Huebner Oaks
R/Afkarena
Flights To Frankfort Kentucky
Calmspirits Clapper
Hca Florida Middleburg Emergency Reviews
Pac Man Deviantart
Straight Talk Phones With 7 Inch Screen
WEB.DE Apps zum mailen auf dem SmartPhone, für Ihren Browser und Computer.
Weather Rotterdam - Detailed bulletin - Free 15-day Marine forecasts - METEO CONSULT MARINE
Las 12 mejores subastas de carros en Los Ángeles, California - Gossip Vehiculos
Vipleaguenba
Race Karts For Sale Near Me
Tyler Sis University City
R. Kelly Net Worth 2024: The King Of R&B's Rise And Fall
[PDF] PDF - Education Update - Free Download PDF
Weve Got You Surrounded Meme
Bill Remini Obituary
Crossword Help - Find Missing Letters & Solve Clues
Vivaciousveteran
What Individuals Need to Know When Raising Money for a Charitable Cause
Arrest Gif
Stickley Furniture
How To Improve Your Pilates C-Curve
ShadowCat - Forestry Mulching, Land Clearing, Bush Hog, Brush, Bobcat - farm & garden services - craigslist
Ma Scratch Tickets Codes
Babylon 2022 Showtimes Near Cinemark Downey And Xd
Pinellas Fire Active Calls
20 bank M&A deals with the largest target asset volume in 2023
Weather Underground Cedar Rapids
Emily Browning Fansite
Avance Primary Care Morrisville
Powerspec G512
Noh Buddy
Oklahoma City Farm & Garden Craigslist
Craigslist Houses For Rent Little River Sc
Playboi Carti Heardle
Yosemite Sam Hood Ornament
Mejores páginas para ver deportes gratis y online - VidaBytes
Vrca File Converter
Noaa Duluth Mn
Latest Posts
Article information

Author: Van Hayes

Last Updated:

Views: 6236

Rating: 4.6 / 5 (46 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Van Hayes

Birthday: 1994-06-07

Address: 2004 Kling Rapid, New Destiny, MT 64658-2367

Phone: +512425013758

Job: National Farming Director

Hobby: Reading, Polo, Genealogy, amateur radio, Scouting, Stand-up comedy, Cryptography

Introduction: My name is Van Hayes, I am a thankful, friendly, smiling, calm, powerful, fine, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.