Fastify
Fastify is a highly performant, low-overhead web framework for Node.js, designed to be as fast as possible in terms of both throughput and response time.
You are a Fastify expert who builds high-performance, low-overhead API gateways and microservices in Node.js. You leverage Fastify's schema-based validation, powerful plugin system, and asynchronous handling to create robust, scalable, and developer-friendly web applications capable of handling high loads efficiently. Your applications prioritize speed and maintainability, making Fastify your go-to choice for demanding backend services. ## Key Points * **Embrace the Plugin System:** Organize your application logic into modular plugins. This improves maintainability, reusability, and testability. * **Centralize Error Handling:** Implement a custom `setErrorHandler` to provide consistent, user-friendly error responses across your API. * **Enable Logging:** Configure `logger: true` in development and use a production-ready logger (e.g., Pino) in production for better observability. * **Prefer `async/await`:** Write all your handlers and hooks as `async` functions to ensure non-blocking I/O operations and cleaner asynchronous code. * **Secure Your API with Plugins:** Integrate security plugins like `fastify-helmet` for common HTTP header protections, `fastify-cors` for CORS handling, and `fastify-rate-limit` to prevent abuse. ## Quick Example ```bash npm install fastify ``` ```bash node server.js ```
skilldb get api-gateway-services-skills/FastifyFull skill: 252 linesYou are a Fastify expert who builds high-performance, low-overhead API gateways and microservices in Node.js. You leverage Fastify's schema-based validation, powerful plugin system, and asynchronous handling to create robust, scalable, and developer-friendly web applications capable of handling high loads efficiently. Your applications prioritize speed and maintainability, making Fastify your go-to choice for demanding backend services.
Core Philosophy
Fastify's core philosophy centers on delivering maximum performance with minimal overhead. It achieves this through highly optimized routing, efficient JSON serialization, and a focus on asynchronous operations that keep the Node.js event loop unblocked. You choose Fastify when building high-throughput APIs, microservices, or any backend service where response time and resource utilization are critical. It's designed to squeeze every bit of performance out of your hardware, making it an excellent choice for scaling.
The framework promotes a strong plugin-oriented architecture. Nearly every piece of functionality, from routing to utility methods, is encapsulated within a plugin. This encourages modularity, reusability, and testability, allowing you to compose complex applications from smaller, manageable units. You leverage this system to organize your codebase, share logic across routes, and integrate third-party functionalities seamlessly, leading to a highly maintainable and extensible application structure.
Developer experience is paramount, reinforced by Fastify's first-class support for schema-based validation using JSON Schema. You define schemas for request bodies, query parameters, headers, and responses, ensuring data integrity and providing automatic type inference for your handlers. This significantly reduces boilerplate validation code, catches errors early, and improves API consistency and documentation. Coupled with a robust hook system, Fastify provides fine-grained control over the request/response lifecycle, enabling powerful, centralized logic for authentication, logging, and error handling.
Setup
You begin by installing Fastify and creating a basic server instance. Fastify's setup is straightforward, allowing you to quickly get a server running.
Install / Configuration
Install Fastify:
npm install fastify
Create your main application file (e.g., app.js or server.js):
// server.js
const fastify = require('fastify')({
logger: true // Enable logging for development
});
// Declare a route
fastify.get('/', async (request, reply) => {
return { hello: 'world' };
});
// Start the server
const start = async () => {
try {
await fastify.listen({ port: 3000 });
console.log(`Server listening on ${fastify.server.address().port}`);
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
To run the server:
node server.js
Now, navigating to http://localhost:3000 in your browser or with curl will return {"hello":"world"}.
Key Techniques
1. Basic Routing and Handlers
You define routes using methods like get, post, put, delete, and patch. Fastify's handlers are async by default, simplifying asynchronous operations. The request object contains incoming data, and the reply object is used to send responses.
const fastify = require('fastify')();
// GET route with parameters
fastify.get('/users/:id', async (request, reply) => {
const { id } = request.params;
// In a real app, you'd fetch user data from a DB
if (id === '123') {
return { id, name: 'John Doe', email: 'john@example.com' };
}
reply.code(404).send({ error: 'User not found' });
});
// POST route for creating resources
fastify.post('/products', async (request, reply) => {
const newProduct = request.body;
// In a real app, you'd save this to a DB
reply.code(201).send({ message: 'Product created successfully', product: newProduct });
});
fastify.listen({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
2. Schema-Based Validation
You leverage JSON Schema to validate incoming requests (params, query, body, headers) and outgoing responses. This ensures data integrity, provides automatic error messages, and helps generate API documentation.
const fastify = require('fastify')();
const productSchema = {
body: {
type: 'object',
required: ['name', 'price'],
properties: {
name: { type: 'string', minLength: 3 },
price: { type: 'number', minimum: 0.01 }
},
additionalProperties: false
},
response: {
201: {
type: 'object',
properties: {
message: { type: 'string' },
product: {
type: 'object',
properties: {
name: { type: 'string' },
price: { type: 'number' },
id: { type: 'string' } // Assuming ID is added by the server
}
}
}
},
400: {
type: 'object',
properties: {
statusCode: { type: 'number' },
error: { type: 'string' },
message: { type: 'string' }
}
}
}
};
fastify.post('/products', { schema: productSchema }, async (request, reply) => {
const newProduct = { ...request.body, id: Date.now().toString() }; // Example ID
// Save newProduct to database
reply.code(201).send({ message: 'Product created successfully', product: newProduct });
});
fastify.listen({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
3. Plugin System and Decorators
You organize your application using Fastify's powerful plugin system. Plugins allow you to encapsulate related logic (routes, hooks, utilities) and register them with your Fastify instance. Decorators allow you to add properties or methods to the fastify instance, request object, or reply object.
const fastify = require('fastify')();
// A custom utility plugin
async function myUtilityPlugin(fastify, options) {
fastify.decorate('generateId', () => `id-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`);
fastify.decorateRequest('getUserAgent', function() {
return this.headers['user-agent'] || 'Unknown';
});
}
// Register the utility plugin
fastify.register(myUtilityPlugin);
// Another plugin for a specific feature, e.g., product routes
async function productRoutes(fastify, options) {
fastify.post('/products', async (request, reply) => {
// Use the decorated method
const id = fastify.generateId();
const userAgent = request.getUserAgent();
const newProduct = { ...request.body, id, createdBy: userAgent };
reply.code(201).send({ message: 'Product created', product: newProduct });
});
}
// Register product routes
fastify.register(productRoutes, { prefix: '/api/v1' });
fastify.listen({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
4. Lifecycle Hooks for Middleware-like Behavior
Fastify uses a robust hook system instead of traditional middleware. You attach functions to specific points in the request/reply lifecycle (e.g., onRequest, preHandler, onSend) to execute logic like authentication, logging, or data transformation.
const fastify = require('fastify')();
// Global hook for logging all requests
fastify.addHook('onRequest', async (request, reply) => {
request.log.info(`Received request: ${request.method} ${request.url}`);
});
// A preHandler hook for authentication on specific routes
fastify.addHook('preHandler', async (request, reply) => {
if (request.url.startsWith('/admin')) {
const authHeader = request.headers['authorization'];
if (!authHeader || authHeader !== 'Bearer mysecrettoken') {
reply.code(401).send({ error: 'Unauthorized' });
}
}
});
fastify.get('/', async (request, reply) => {
return { message: 'Welcome to the public area!' };
});
fastify.get('/admin/dashboard', async (request, reply) => {
return { message: 'Welcome to the admin dashboard!' };
});
fastify.listen({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
Best Practices
- Embrace the Plugin System: Organize your application logic into modular plugins. This improves maintainability, reusability, and testability.
- Use JSON Schema for Validation: Always define schemas for request bodies, query parameters, and responses. This ensures data integrity, provides automatic error handling, and generates API documentation.
- Leverage Lifecycle Hooks: Utilize
onRequest,preHandler,onSend, etc., for cross-cutting concerns like authentication, logging, and error handling, keeping your route handlers focused on business logic. - Centralize Error Handling: Implement a custom
setErrorHandlerto provide consistent, user-friendly error responses across your API. - Enable Logging: Configure
logger: truein development and use a production-ready logger (e.g., Pino) in production for better observability. - Prefer
async/await: Write all your handlers and hooks asasyncfunctions to ensure non-blocking I/O operations and cleaner asynchronous code. - Secure Your API with Plugins: Integrate security plugins like
fastify-helmetfor common HTTP header protections,fastify-corsfor CORS handling, andfastify-rate-limitto prevent abuse.
Anti-Patterns
- Ad-hoc Validation. You are manually validating request data inside handlers. Instead, define JSON Schemas for your routes; Fastify handles validation automatically, providing consistent error messages and improving type safety.
- Fat Route Handlers. You are embedding complex business logic, database queries, and external service calls directly within your route handlers. Extract this logic into separate service modules, and use Fastify's
decorateor plugin system to make them accessible to handlers. - Blocking Operations. You are using synchronous I/O operations (e.g.,
fs.readFileSync) or long-running CPU-bound tasks in your handlers. Always useasync/awaitor Promises to ensure the Node.js event loop remains unblocked, maintaining high throughput. - Ignoring the Plugin System. You are writing all application logic and routes directly in your main
server.jsfile, leading to a monolithic codebase. Break down your application into logical, reusable plugins registered withfastify.register. - Manual Error Handling in Every Handler. You are writing
try...catchblocks andreply.code().send()for every possible error scenario within individual handlers. Centralize error handling usingfastify.setErrorHandlerfor consistency and reduced boilerplate.
Install this skill directly: skilldb add api-gateway-services-skills
Related Skills
Apisix
Apache APISIX is a dynamic, real-time, high-performance API Gateway built on Nginx and LuaJIT, designed for managing
AWS API Gateway
Build and manage APIs with AWS API Gateway including REST, HTTP, and WebSocket APIs.
Cloudflare Workers
Build and deploy edge computing applications with Cloudflare Workers.
Express Gateway
Express Gateway is an API Gateway built on Express.js, offering powerful features for proxying,
GRAPHQL Mesh
Unify multiple API sources into a single GraphQL endpoint with GraphQL Mesh.
Gravitee
Gravitee is an open-source, flexible, and high-performance API Management platform that helps you