What is Fastify? A complete guide on lightning-fast Node.js plugin
Written by
Zuzanna Olszewska
Published on
October 17, 2023
TL;DR
In the bustling world of web development, Fastify stands out as a game-changing framework for Node.js, favored by 60% of developers. Thanks to its robust plugin architecture, it excels in creating high-speed HTTP APIs with minimal effort. Read to learn about Fastify's unique features and why it's rapidly becoming the go-to choice for efficient, secure web development solutions.
Oops! Something went wrong while submitting the form.
Share
Fastify - the speed demon of web frameworks
Web frameworks simplify development by offering high-level APIs for abstract access to system resources. In the current web landscape, 60% of developers opt for client-side or server-side frameworks. Java, with its array of frameworks, stands out as a significant contender.
Frameworks like Express facilitate API creation with Node.js, but they have limitations. Addressing these, Java introduced Fastify for precise and efficient solutions.
Let's explore Fastify's key features and understand why it's gaining rapid popularity!
What is Fastify?
Fastify, being a cutting-edge framework for Node.js, redefines the web development experience. The reason behind its smooth working is a robust plugin architecture. Inspired by Hapi, Restify, and Express, Fastify.js stands out as a versatile solution for web development needs.
Fastify node.js is not just another framework. Rather, it excels in crafting high-speed HTTP API and uses JSON as the data format. Being highly efficient, Fastify.js allows developers to create lightning-fast APIs with minimal effort. Developers then test these APIs with Java by setting up a Fastify server, defining routes, and then using a Java HTTP client to interact with those routes.
Moreover, it prioritizes maximizing server resources. It also handles a large number of requests without compromising on number of resources. Without a doubt, the Fastify framework is a go-to choice for developers seeking a resource-efficient framework that also maintains crucial elements like security and convenient development.
Core features of Fastify – a Node.js framework
Fastify.js is a fast and flexible server-side templating engine. It supports all of the features you’d expect from a full-featured templating engine:
1. Efficient routing
Fastify routes data through a central router. This router translates requests into HTTP requests and routes them to the appropriate handler. Pure JavaScript implements this router and does not require any external dependencies on third-party services or libraries. This way, Fastify APIs run in Node or any browser that doesn’t support routing.
2. Schema-based validation
Fastify APIs validate request schemas against built-in schemas as well as custom ones provided by plugins. Built-in schemas are used for common data types like integers or strings; custom schemas can extend this by defining additional validation rules.
The schema validation process is asynchronous, so the app can continue to serve requests while validating them without blocking other parts of the application.
3. Extensibility through hooks
Hooks in the Fastify framework provide specific entry points in the application lifecycle where developers can inject custom logic. This enables developers to extend and customize Fastify’s behavior. Moreover, this flexibility enables developers to intervene at crucial stages, ensuring a seamless integration of tailored solutions and the incorporation of additional functionalities.
This not only promotes a high level of customization but also contributes to the adaptability and versatility of Fastify node.js for a diverse range of web development scenarios.
4. Powerful plugin architecture
The core of Fastify working is its robust plugin architecture that offers a powerful mechanism for enhancing the framework’s functionality. The developers can integrate plugins seamlessly and can encapsulate specific features with modern modular units.
This way, developers can access a clean and organized code structure. Additionally, this plugin architecture facilitates a scalable development process that encourages the creation of modular components that can be reused easily. This modern development practice makes Fastify an ideal choice for building dynamic and feature-rich web applications.
5. Fast HTTP API development
Fastify makes it easy to build RESTful APIs with minimal overhead. The Fastify HTTP API module provides an HTTP adapter that allows you to use standard request/response patterns in your application code without any changes to your application logic or configuration.
Fastify vs. express
Here’s an overview of Fastify vs. Express.
Criteria
Fastify
Express
Focus
Prioritizes minimalism and speed, focusing on efficient APIs.
Embraces flexibility and a more comprehensive approach.
Speed And Scalability
78,956 requests per second
15,978 requests per second
TypeScript Support
Supported (Dependent on Node.js)
Challenges in providing seamless support
Plugins Availability
Extensive plugins available
Limited Plugins
Learning Curve
Straightforward, minimal learning
A steeper learning curve due to more
curve, suitable for beginners.
Community Support
Growing community, active support, and regular updates.
Established a large community with a wealth of resources.
Flexibility
Offers flexibility but is more opinionated for better performance.
Highly flexible, allowing developers to choose their preferred architecture.
Use Cases
Ideal for developing efficient APIs, especially when performance is key.
Versatile and suitable for a wide range of applications, including web servers, APIs, and single-page applications.
Five significant fastify plugins
Let's explore 5 major plugins to enhance the working of Fastify:
1. fastify-swagger
Fastify-swagger generates Swagger/OpenAPI documentation for your Fastify APIs, making it easier to understand and interact with your API.
2. fastify-jwt
Fastify-jwt adds JSON Web Token (JWT) authentication support to Fastify, allowing you to secure your routes with token-based authentication.
3. fastify-multipart
Fastify-multipart enables handling multipart/form-data requests, making it useful for working with file uploads in your Fastify application.
4. fastify-mongoose
Fastify-mongoose integrates Mongoose, an ODM (Object Data Modeling) library for MongoDB, with Fastify, simplifying database interactions.
5. fastify-cors
Fastify-cors provides Cross-Origin Resource Sharing (CORS) support, allowing you to define the access policies for your Fastify server to handle requests from different origins.
Getting started with Fastify for Node.js applications
To integrate Fastify into your project, kick off by installing it:
npm install fastify
Once installed, incorporate it into your project and create a new Fastify server instance:
import Fastify from "fastify"; const fastify = Fastify();
The Fastify function allows customization through an options object. For instance, activating built-in logging and setting a timeout for incoming requests can be done like this:
With your preferred configurations in place, you're set to add your initial route:
fastify.get('/', function (request, reply) { reply.send("Hello world!"); });
Once you've defined your "Hello world!" route, kickstart the server by specifying your chosen localhost port:
const port = process.env.PORT || 3000;
fastify.listen({ port }, function (err, address) { if (err) { fastify.log.error(err); process.exit(1); }
fastify.log.info(`Fastify is listening on port: ${address}`); });
To initiate the server, run the entry file. Expect JSON log output in the console:
{"level":30,"time":1675958171939,"pid":391638,"hostname":"fedora","msg":"Server listening at http://127.0.0.1:3000"} {"level":30,"time":1675958171940,"pid":391638,"hostname":"fedora","msg":"Server listening at http://[::1]:3000"} {"level":30,"time":1675958171940,"pid":391638,"hostname":"fedora","msg":"Fastify is listening on port: http://127.0.0.1:3000"}
Enhance log readability in development using the pino-pretty package. After installation, pipe your program's output to the CLI:
node server.js | pino-pretty
This generates a colored output for easier readability. Enabling the logger is beneficial as it records all incoming requests in a detailed log format, providing a timestamp, request ID, response status code, and response time (in milliseconds):
The logging feature, when activated, proves invaluable by capturing every incoming server request in a detailed log format. Execute the following shell command using curl to observe the logged information:
curl "http://localhost:3000"
The resulting JSON log showcases essential details:
Creating endpoints in Fastify is a breeze with dedicated helper methods. For HTTP GET requests, use fastify.get() as demonstrated earlier. Other methods cater to various HTTP methods:
For a universal handler across all HTTP methods for a specific route, leverage fastify.all():
fastify.all(path, [options], handler);
While the options argument is optional, it offers a spectrum of configuration settings per route. Refer to the Fastify docs for the exhaustive list of available options.
Path arguments can be static (e.g., /about or /settings/profile) or dynamic, with URL parameters accessible in the handler through request.params:
fastify.get("/:userID/repos/:projectID", function (request, reply) { const { userID, projectID } = request.params; // your code here });
Fastify handlers follow a specific signature, with request representing the received HTTP request and reply signifying the response:
function (request, reply) {}
For asynchronous handlers, respond by returning from the function:
fastify.get("/", async function (request, reply) { // do some work return { body: true }; });
In asynchronous handlers, use await reply or return reply to prevent race conditions:
fastify.get("/", async function (request, reply) { // do some work return reply.send({ body: true }); });
Fastify routes inherently catch unhandled exceptions or promise rejections. When such instances occur, the default error handler triggers a '500 Internal Server Error' response:
fastify.get("/", function (request, reply) { throw new Error("Uncaught exception"); });
The corresponding JSON response using curl:
{"statusCode":500,"error":"Internal Server Error","message":"Uncaught exception"}
Tailor the default error-handling behavior using fastify.setErrorHandler().
Maximizing Fastify's capabilities
Let's see what else you can do with Fastify:
Validation: Fastify leverages Ajv under the hood, enabling the definition of validation rules using JSON schema.
Logging: Fastify employs the fast and versatile logger, Pino. The logger instance is readily available on the Fastify server instance
(e.g., Fastify.log.info("...")) and on all Request objects (e.g., request.log.info("...")).
Logger usage is straightforward; however, it needs to be enabled since it is turned off by default.
Error handling: Fastify facilitates error handling through the setErrorHandler() method, allowing developers to explicitly specify a function for error management. Further customization is achievable by specifying different error handlers using plugins. Fastify diligently captures various uncaught errors, whether in
synchronous routes (e.g., app.get('/', () => { throw new Error('kaboom') })) or
asynchronous routes (e.g., app.get('/', async () => { throw new Error('kaboom') })), without compromising performance.
Decorators: Fastify introduces decorators, empowering developers to tailor core Fastify objects such as the server instance, request, and reply objects used during the HTTP request lifecycle. The decorator API facilitates the attachment of various properties, including functions, plain objects, or native types, to these core objects. This capability enhances customization, allowing developers to tailor Fastify to specific project needs.
Final words
Fastify isn't just a framework; it's a robust toolkit empowering easy development of high-performance Node.js applications. Prioritizing speed and scalability, it's the ideal choice for modern, reliable APIs.
Partner with Apptensions, where our expertise transforms ideas into transformative digital experiences. Explore possibilities; let's navigate complexities together for your project's success.