🎯 Ejemplos recomendados
Balanced sample collections from various categories for you to explore
Ejemplos de Fastify
Ejemplos del framework web Node.js de alto rendimiento Fastify incluyendo plugins, hooks, validación y técnicas de optimización
💻 Hola Mundo con Fastify javascript
🟢 simple
Configuración básica del servidor Fastify con rutas, middleware y características esenciales para aplicaciones web de alto rendimiento
// Fastify Hello World Examples
// 1. Basic Fastify Server
const fastify = require('fastify')({ logger: true });
// Declare a route
fastify.get('/', async (request, reply) => {
return { hello: 'world' };
});
// Run the server
const start = async () => {
try {
await fastify.listen(3000);
console.log('Server listening on http://localhost:3000');
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
// 2. Fastify with TypeScript
// src/server.ts
import fastify from 'fastify';
import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
const server: FastifyInstance = fastify({
logger: {
level: 'info',
prettyPrint: true,
},
});
// Define routes
server.get('/', async (request: FastifyRequest, reply: FastifyReply) => {
return {
message: 'Hello Fastify with TypeScript!',
timestamp: new Date().toISOString(),
version: '1.0.0'
};
});
server.get('/health', async (request: FastifyRequest, reply: FastifyReply) => {
return {
status: 'ok',
uptime: process.uptime(),
memory: process.memoryUsage()
};
});
// Start server
const start = async () => {
try {
const port = parseInt(process.env.PORT || '3000');
const host = process.env.HOST || '0.0.0.0';
await server.listen({ port, host });
console.log(`🚀 Server ready at http://${host}:${port}`);
} catch (err) {
server.log.error(err);
process.exit(1);
}
};
start();
// 3. Fastify with Route Parameters and Validation
const fastify = require('fastify')({ logger: true });
// User data store (in production, use a database)
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]', age: 30 },
{ id: 2, name: 'Jane Smith', email: '[email protected]', age: 25 },
{ id: 3, name: 'Bob Johnson', email: '[email protected]', age: 35 }
];
// Define schemas for validation
const userSchema = {
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'number', minimum: 0, maximum: 150 }
},
required: ['name', 'email']
};
const createUserSchema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'number', minimum: 0, maximum: 150 }
},
required: ['name', 'email']
};
// Routes with validation
fastify.get('/api/users', {
schema: {
description: 'Get all users',
tags: ['users'],
response: {
200: {
type: 'array',
items: userSchema
}
}
}
}, async (request, reply) => {
return { users, total: users.length };
});
fastify.get('/api/users/:id', {
schema: {
description: 'Get user by ID',
tags: ['users'],
params: {
type: 'object',
properties: {
id: { type: 'number' }
}
},
response: {
200: userSchema,
404: {
type: 'object',
properties: {
error: { type: 'string' }
}
}
}
}
}, async (request, reply) => {
const { id } = request.params;
const user = users.find(u => u.id === id);
if (!user) {
reply.code(404).send({ error: 'User not found' });
return;
}
return user;
});
fastify.post('/api/users', {
schema: {
description: 'Create a new user',
tags: ['users'],
body: createUserSchema,
response: {
201: userSchema,
400: {
type: 'object',
properties: {
error: { type: 'string' }
}
}
}
}
}, async (request, reply) => {
const newUser = {
id: users.length + 1,
...request.body
};
users.push(newUser);
reply.code(201).send(newUser);
});
// 4. Fastify with Hooks and Middleware
const fastify = require('fastify')({ logger: true });
// Global hooks
fastify.addHook('onRequest', async (request, reply) => {
const start = Date.now();
request.startTime = start;
});
fastify.addHook('onResponse', async (request, reply) => {
const duration = Date.now() - request.startTime;
fastify.log.info(`Request to ${request.url} took ${duration}ms`);
});
// Authentication hook
fastify.addHook('preHandler', async (request, reply) => {
// Skip auth for certain routes
if (request.url.startsWith('/public') || request.url === '/') {
return;
}
const authHeader = request.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
reply.code(401).send({ error: 'Unauthorized' });
return;
}
// In production, verify JWT token here
const token = authHeader.substring(7);
if (token !== 'valid-token') {
reply.code(401).send({ error: 'Invalid token' });
return;
}
// Add user info to request
request.user = { id: 1, name: 'Authenticated User' };
});
// Public routes
fastify.get('/public/info', async (request, reply) => {
return { message: 'This is public information', timestamp: new Date().toISOString() };
});
// Protected routes
fastify.get('/protected/data', async (request, reply) => {
return {
message: 'This is protected data',
user: request.user,
timestamp: new Date().toISOString()
};
});
// 5. Fastify with Plugins
// plugins/auth.js
const fp = require('fastify-plugin');
async function authPlugin(fastify, options) {
fastify.decorate('authenticate', async (request, reply) => {
try {
await request.jwtVerify();
} catch (err) {
reply.send(err);
}
});
}
module.exports = fp(authPlugin);
// plugins/database.js
const fp = require('fastify-plugin');
async function databasePlugin(fastify, options) {
// Mock database connection
const db = {
users: [],
posts: [],
async getUser(id) {
return this.users.find(user => user.id === id);
},
async createUser(userData) {
const user = { id: this.users.length + 1, ...userData };
this.users.push(user);
return user;
}
};
fastify.decorate('db', db);
}
module.exports = fp(databasePlugin);
// Main server with plugins
const fastify = require('fastify')({ logger: true });
// Register plugins
fastify.register(require('fastify-jwt'), { secret: 'supersecret' });
fastify.register(require('./plugins/auth'));
fastify.register(require('./plugins/database'));
// Routes using plugins
fastify.get('/api/profile', {
preHandler: [fastify.authenticate]
}, async (request, reply) => {
const user = await fastify.db.getUser(request.user.id);
return { user };
});
fastify.post('/api/users', async (request, reply) => {
const user = await fastify.db.createUser(request.body);
return user;
});
// 6. Fastify with File Uploads
const fastify = require('fastify')({ logger: true });
const path = require('path');
const fs = require('fs').promises;
// Register multipart plugin for file uploads
fastify.register(require('fastify-multipart'));
// Ensure upload directory exists
const uploadDir = path.join(__dirname, 'uploads');
fs.mkdir(uploadDir, { recursive: true }).catch(console.error);
// File upload route
fastify.post('/upload', async (request, reply) => {
try {
const data = await request.file();
if (!data) {
reply.code(400).send({ error: 'No file uploaded' });
return;
}
// Generate unique filename
const filename = `${Date.now()}-${data.filename}`;
const filepath = path.join(uploadDir, filename);
// Save file
await pump(data.file, fs.createWriteStream(filepath));
reply.send({
message: 'File uploaded successfully',
filename,
size: data.file.bytesRead
});
} catch (error) {
fastify.log.error(error);
reply.code(500).send({ error: 'File upload failed' });
}
});
// Multiple files upload
fastify.post('/upload/multiple', async (request, reply) => {
try {
const files = [];
const parts = request.files();
for await (const part of parts) {
const filename = `${Date.now()}-${part.filename}`;
const filepath = path.join(uploadDir, filename);
await pump(part.file, fs.createWriteStream(filepath));
files.push({
filename,
originalName: part.filename,
size: part.file.bytesRead
});
}
reply.send({
message: 'Files uploaded successfully',
files,
count: files.length
});
} catch (error) {
fastify.log.error(error);
reply.code(500).send({ error: 'Multiple file upload failed' });
}
});
// 7. Fastify with Error Handling
const fastify = require('fastify')({ logger: true });
// Custom error class
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.isOperational = true;
}
}
// Set error handler
fastify.setErrorHandler(function (error, request, reply) {
// Log error
this.log.error(error);
// Send error response
if (error.validation) {
// Validation error
reply.code(400).send({
error: 'Validation Error',
details: error.validation,
statusCode: 400
});
return;
}
if (error.isOperational) {
// Operational error (expected)
reply.code(error.statusCode || 500).send({
error: error.message,
statusCode: error.statusCode || 500
});
} else {
// Programming error
reply.code(500).send({
error: 'Internal Server Error',
statusCode: 500
});
}
});
// Route that throws different errors
fastify.get('/error/validation', {
schema: {
querystring: {
type: 'object',
properties: {
name: { type: 'string', minLength: 3 }
},
required: ['name']
}
}
}, async (request, reply) => {
// This will cause validation error if name is too short
return { message: `Hello ${request.query.name}` };
});
fastify.get('/error/operational', async (request, reply) => {
throw new AppError('This is an operational error', 400);
});
fastify.get('/error/programming', async (request, reply) => {
// This will be caught as a programming error
throw new Error('Unexpected error occurred');
});
// 8. Fastify with Environment Configuration
const fastify = require('fastify')({
logger: {
level: process.env.LOG_LEVEL || 'info'
}
});
// Configuration
const config = {
port: parseInt(process.env.PORT || 3000),
host: process.env.HOST || '0.0.0.0',
database: {
url: process.env.DATABASE_URL || 'mongodb://localhost:27017/fastify',
name: process.env.DATABASE_NAME || 'fastify_db'
},
jwt: {
secret: process.env.JWT_SECRET || 'fallback-secret-key'
},
cors: {
origin: process.env.CORS_ORIGIN || '*',
credentials: true
}
};
// Register environment-specific plugins
if (process.env.NODE_ENV === 'development') {
fastify.register(require('fastify-cors'), config.cors);
}
// Health check endpoint
fastify.get('/health', async (request, reply) => {
return {
status: 'ok',
environment: process.env.NODE_ENV || 'development',
uptime: process.uptime(),
memory: process.memoryUsage(),
config: {
port: config.port,
databaseName: config.database.name
}
};
});
// 9. Fastify with Testing Setup
// test/server.test.js
const { test } = require('tap');
const build = require('../server');
test('GET / route', async t => {
const app = build();
const response = await app.inject({
method: 'GET',
url: '/'
});
t.equal(response.statusCode, 200);
t.same(response.json(), { hello: 'world' });
});
test('POST /api/users with valid data', async t => {
const app = build();
const userData = {
name: 'Test User',
email: '[email protected]',
age: 25
};
const response = await app.inject({
method: 'POST',
url: '/api/users',
payload: userData
});
t.equal(response.statusCode, 201);
t.match(response.json(), userData);
});
test('POST /api/users with invalid data', async t => {
const app = build();
const invalidData = {
name: '', // Invalid: empty string
email: 'invalid-email' // Invalid: not a valid email
};
const response = await app.inject({
method: 'POST',
url: '/api/users',
payload: invalidData
});
t.equal(response.statusCode, 400);
t.ok(response.json().validation);
});
// 10. Fastify Production Best Practices
const fastify = require('fastify')({
logger: {
level: process.env.LOG_LEVEL || 'info',
stream: process.stdout
},
// Enable trust proxy for proper IP logging behind reverse proxy
trustProxy: true
});
// Graceful shutdown
process.on('SIGINT', async () => {
fastify.log.info('Received SIGINT, shutting down gracefully...');
await fastify.close();
process.exit(0);
});
process.on('SIGTERM', async () => {
fastify.log.info('Received SIGTERM, shutting down gracefully...');
await fastify.close();
process.exit(0);
});
// Health check for load balancers
fastify.get('/health', {
schema: {
hide: true // Hide from documentation
}
}, async (request, reply) => {
return { status: 'ok' };
});
// Production-ready startup
const start = async () => {
try {
const port = parseInt(process.env.PORT || 3000);
await fastify.listen({
port,
host: '0.0.0.0' // Listen on all interfaces
});
fastify.log.info(`🚀 Server ready on port ${port}`);
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();