Conceptos básicos de Fastify
10 ejemplos para construir tu primera API de Fastify 5 - 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para construir tu primera API de Fastify 5 - 7 básicos y 3 intermedios.
mkdir fastify-api && cd fastify-api
npm init -y
npm pkg set type=module
npm install fastify@5
npm install -D typescript@5.6 tsxPara la validación de esquemas y patrones de plugins, consulta Validación de esquemas JSON y Plugins de Fastify.
import Fastify from "fastify";
const app = Fastify({ logger: true });
app.get("/", async () => {
return { message: "Hello from Fastify 5" };
});
await app.listen({ port: 3000, host: "0.0.0.0" });logger: true habilita Pino con valores predeterminados sensatosawait app.listen() (escucha asíncrona de Fastify 5)import Fastify from "fastify";
const app = Fastify();
app.get("/users/:id", {
schema: {
params: {
type: "object",
properties: { id: { type: "string", format: "uuid" } },
required: ["id"],
},
response: {
200: {
type: "object",
properties: { id: { type: "string" }, name: { type: "string" } },
},
},
},
}, async (req) => {
return { id: req.params.id, name: "Ada Lovelace" };
});import Fastify from "fastify";
const app = Fastify();
app.post("/users", {
schema: {
body: {
type: "object",
required: ["name", "email"],
properties: {
name: { type: "string", minLength: 1 },
email: { type: "string", format: "email" },
},
},
},
}, async (req, reply) => {
const { name, email } = req.body as { name: string; email: string };
return reply.status(201).send({ id: "1", name, email });
});reply.status(201).send() para códigos de estado explícitosimport Fastify from "fastify";
const app = Fastify();
app.register(async function userRoutes(fastify) {
fastify.get("/", async () => [{ id: 1, name: "Ada" }]);
fastify.get("/:id", async (req) => ({ id: (req.params as { id: string }).id }));
}, { prefix: "/users" });register crea un ámbito encapsuladoprefix monta todas las rutas bajo /usersimport Fastify from "fastify";
const app = Fastify({ logger: true });
app.addHook("onRequest", async (req) => {
req.headers["x-request-start"] = String(Date.now());
});
app.addHook("onResponse", async (req, reply) => {
const start = Number(req.headers["x-request-start"]);
req.log.info({ duration: Date.now() - start, status: reply.statusCode });
});
app.get("/health", async () => ({ ok: true }));onRequest se ejecuta antes del enrutamiento; preHandler se ejecuta antes del manejadorimport Fastify from "fastify";
const app = Fastify();
app.setErrorHandler((err, _req, reply) => {
const status = err.statusCode ?? 500;
reply.status(status).send({
error: status === 500 ? "Internal server error" : err.message,
});
});
app.get("/fail", async () => {
throw Object.assign(new Error("Not found"), { statusCode: 404 });
});setErrorHandler es el manejador de errores centralizadostatusCode a los errores para errores operacionalesstatusCode: 400import Fastify from "fastify";
const app = Fastify({
logger: {
level: process.env.LOG_LEVEL ?? "info",
transport: process.env.NODE_ENV === "development"
? { target: "pino-pretty" }
: undefined,
},
});
app.get("/users", async (req) => {
req.log.info({ action: "list_users" });
return [];
});req.log es un logger hijo con contexto de solicitudimport Fastify from "fastify";
import fp from "fastify-plugin";
const authPlugin = fp(async (fastify) => {
fastify.decorate("authenticate", async (req: { headers: { authorization?: string } }) => {
if (!req.headers.authorization) throw Object.assign(new Error("Unauthorized"), { statusCode: 401 });
});
});
const app = Fastify();
await app.register(authPlugin);
// authenticate está disponible en todos los ámbitosfastify-plugin, los decoradores tienen un ámbito limitado al plugin que los registrafp para autenticación compartida, conexiones a bases de datos y configuraciónimport Fastify from "fastify";
import { test } from "node:test";
import assert from "node:assert/strict";
const app = Fastify();
app.get("/health", async () => ({ ok: true }));
test("GET /health", async () => {
const res = await app.inject({ method: "GET", url: "/health" });
assert.equal(res.statusCode, 200);
assert.deepEqual(res.json(), { ok: true });
});inject() simula HTTP sin E/S de redimport Fastify from "fastify";
const app = Fastify();
await app.listen({ port: 3000 });
const server = app.server;
server.keepAliveTimeout = 65_000;
server.headersTimeout = 66_000;
server.requestTimeout = 30_000;app.server después de escucharA través de @fastify/express o middie, pero prefiere los plugins nativos de Fastify. El middleware de Express pierde los beneficios de la validación de esquemas.
Fastify para rendimiento y APIs schema-first. Express para máximo ecosistema y familiaridad del equipo. Consulta Fastify vs Express ADR.
Sí. Fastify 5 es ESM-first. Usa import Fastify from "fastify".
Usa fastify-type-provider-zod o @fastify/type-provider-typebox para tipos inferidos de esquemas.
Sí. NestFactory.create(AppModule, new FastifyAdapter()). Consulta Conceptos básicos de NestJS.
Versiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS activa), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.
Revisado por Chris St. John·Última actualización: 16 jul 2026