Alejandría

Busca en Alejandría

Lenguajes y marcos

Fastify

Construye APIs Node.js con esquemas y plugins encapsulados.

01

En pocas palabras

Framework web de Node.js para crear APIs y servicios con bajo costo de procesamiento, validación por esquemas y plugins encapsulados.

Qué problema resuelve

Trabajo repetitivo de rutas, validación, serialización y registro de eventos al construir servicios HTTP.

Cuándo utilizarlo

APIs JSON, microservicios y backends en JavaScript o TypeScript. Ejemplo: publicar un endpoint cuyo esquema valida la petición y controla la serialización de la respuesta.

02

De la idea a la práctica

Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.

Cómo funciona

Fastify organiza rutas, hooks y plugins. Los esquemas permiten validar entradas y compilar la serialización de respuestas. La encapsulación ayuda a delimitar el alcance de configuraciones y extensiones.

Ejemplo: un servicio mínimo

Con fastify instalado y un proyecto configurado como módulo ES:

import Fastify from 'fastify';

const app = Fastify({ logger: true });
app.get('/salud', async () => ({ ok: true }));
await app.listen({ port: 3000, host: '127.0.0.1' });

Ruta con esquema de entrada y salida

app.post(
  '/v1/solicitudes',
  {
    schema: {
      body: {
        type: 'object',
        required: ['documento', 'monto', 'plazo'],
        additionalProperties: false,
        properties: {
          documento: { type: 'string', pattern: '^[0-9]{6,10}$' },
          monto: { type: 'number', minimum: 100000 },
          plazo: { type: 'integer', minimum: 3, maximum: 60 },
        },
      },
      response: {
        202: {
          type: 'object',
          properties: { id: { type: 'string' }, estado: { type: 'string' } },
        },
      },
    },
  },
  async (request, reply) => {
    const solicitud = await app.solicitudes.crear(request.body);
    return reply.code(202).send(solicitud);
  },
);

El esquema de respuesta no solo acelera la serialización: impide filtrar campos no declarados (por ejemplo, datos internos que vengan del repositorio). Con un type provider como TypeBox o Zod, los tipos de TypeScript se derivan del mismo esquema.

Plugins y encapsulación

// plugins/db.js — compartido con toda la app gracias a fastify-plugin
import fp from 'fastify-plugin';
export default fp(async (app) => {
  const pool = crearPool(process.env.DATABASE_URL);
  app.decorate('db', pool);
  app.addHook('onClose', async () => pool.end());
});

// rutas/admin.js — hooks que solo afectan a este contexto
export default async (app) => {
  app.addHook('onRequest', app.verificarRol('admin'));
  app.get('/usuarios', async () => app.db.query('SELECT …'));
};

app.register(db);
app.register(admin, { prefix: '/admin' });

Sin fastify-plugin, lo que registra un plugin queda encapsulado en su contexto: es la forma de aislar módulos.

Ciclo de vida de una petición

onRequest → preParsing → preValidation → validación → preHandler → handler → preSerialization → onSend → onResponse. Autenticación en onRequest, autorización por recurso en preHandler.

Plugins habituales

Plugin Para qué
@fastify/helmet Cabeceras de seguridad
@fastify/rate-limit Límite de peticiones
@fastify/cors CORS
@fastify/jwt Autenticación con JWT
@fastify/swagger OpenAPI generado desde los esquemas
@fastify/under-pressure Rechazar carga cuando el proceso se satura

Pruebas sin levantar el servidor

const res = await app.inject({
  method: 'POST',
  url: '/v1/solicitudes',
  payload: { documento: '123' },
});
assert.equal(res.statusCode, 400);

inject ejecuta toda la cadena de hooks y validación en memoria, ideal para pruebas rápidas. El logger integrado es Pino (JSON estructurado), que encaja con Grafana Loki u OpenTelemetry.

Criterios de implementación

Añade esquemas a las rutas públicas y separa plugins por responsabilidad. Integra gestión de errores, límites de petición y apagado ordenado. Mide rendimiento con las dependencias reales; un endpoint vacío no representa una aplicación completa.

Continúa en las fuentes

Documentación oficial para verificar detalles y explorar más.