Validación de Esquema JSON
Usa el Esquema JSON incorporado de Fastify para la validación de solicitudes y la serialización de respuestas compiladas.
Receta
Tarjeta de receta de referencia rápida: lista para copiar y pegar.
import Fastify from "fastify";
const app = Fastify();
const userSchema = {
type: "object",
required: ["name", "email"],
properties: {
name: { type: "string", minLength: 1, maxLength: 100 },
email: { type: "string", format: "email" },
},
} as const;
app.post("/users", {
schema: {
body: userSchema,
response: {
201: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
email: { type: "string" },
},
},
},
},
}, async (req, reply) => {
const body = req.body as { name: string; email: string };
return reply.status(201).send({ id: crypto.randomUUID(), ...body });
});Cuándo usarlo: Cada endpoint de API público. La validación de esquemas es la principal ventaja de Fastify sobre Express.
Ejemplo de trabajo
import Fastify from "fastify";
import { Type } from "@sinclair/typebox";
import { TypeBoxTypeProvider } from "@fastify/type-provider-typebox";
const app = Fastify().withTypeProvider<TypeBoxTypeProvider>();
const CreateUser = Type.Object({
name: Type.String({ minLength: 1 }),
email: Type.String({ format: "email" }),
});
const UserResponse = Type.Object({
id: Type.String({ format: "uuid" }),
name: Type.String(),
email: Type.String(),
});
app.post("/users", {
schema: {
body: CreateUser,
response: { 201: UserResponse },
},
}, async (req, reply) => {
const { name, email } = req.body;
return reply.status(201).send({ id: crypto.randomUUID(), name, email });
});
app.setErrorHandler((err, _req, reply) => {
if (err.validation) {
return reply.status(400).send({ error: "Validation failed", details: err.validation });
}
reply.status(500).send({ error: "Internal server error" });
});Lo que esto demuestra:
- Esquemas TypeBox con inferencia de tipos de TypeScript
- 400 automático en caso de fallo de validación
- Manejador de errores personalizado para la forma del error de validación
- El esquema de respuesta compila el serializador para mayor velocidad
Análisis Profundo
Cómo funciona
- Fastify usa Ajv para la validación de solicitudes en el momento del registro de la ruta
- Los esquemas de respuesta se compilan en funciones de serialización rápidas (fast-json-stringify)
- La validación se ejecuta en el hook
preValidationantes del manejador - Las respuestas inválidas en desarrollo registran advertencias; en producción se eliminan para que coincidan con el esquema
Cobertura del Esquema
| Parte | Valida | Estado de fallo |
|---|---|---|
body | Cuerpo POST/PUT/PATCH | 400 |
querystring | Parámetros de consulta de URL | 400 |
params | Parámetros de ruta (:id) | 400 |
headers | Encabezados de solicitud | 400 |
response | Valor de retorno del manejador | 500 (serialización) |
Esquemas Reutilizables
app.addSchema({ $id: "User", type: "object", properties: { id: { type: "string" } } });
app.get("/users/:id", {
schema: {
params: { $ref: "User#" },
response: { 200: { $ref: "User#" } },
},
}, async (req) => ({ id: req.params.id }));Errores comunes
- Sin esquema de respuesta - se pierde el beneficio de la velocidad de serialización. Solución: define esquemas de respuesta para todos los endpoints públicos.
additionalPropertiesexcesivamente permisivo - acepta campos inesperados. Solución: estableceadditionalProperties: falseen los objetos.- El esquema y los tipos de TypeScript divergen - el tiempo de ejecución valida una forma, TS asume otra. Solución: usa un proveedor de tipos TypeBox o Zod.
- Los esquemas anidados complejos ralentizan la compilación - el tiempo de inicio aumenta. Solución: reutiliza esquemas con
$refyaddSchema. - Devolver campos que no están en el esquema de respuesta - se eliminan silenciosamente en producción. Solución: haz que la salida del manejador coincida exactamente con el esquema.
- Validar con Zod Y Esquema JSON - costo de validación duplicado. Solución: elige uno; usa
fastify-type-provider-zod.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Proveedor de tipos Zod | El equipo ya está estandarizado en Zod | Máximo rendimiento de serialización (TypeBox/JSON Schema más rápido) |
| Ajv independiente en Express | Atascado en Express | Iniciando un nuevo proyecto Fastify |
| Generación de código OpenAPI | Primero el contrato con consumidores externos | API solo interna |
| Validación manual en el manejador | Solo prototipo rápido | Cualquier endpoint de producción |
Preguntas Frecuentes
¿La validación ralentiza las solicitudes?
La validación añade microsegundos. Los serializadores compilados aceleran las respuestas, a menudo obteniendo una mejora de rendimiento sobre JSON.stringify.
¿Puedo generar OpenAPI a partir de esquemas?
Sí. @fastify/swagger lee los esquemas de ruta y genera la documentación de OpenAPI 3 automáticamente.
¿Cómo valido campos opcionales?
Omítelos del array required. Usa { type: ["string", "null"] } para campos anulables.
¿Qué borrador de Esquema JSON usa Fastify?
Fastify 5 usa Ajv con JSON Schema draft-07 por defecto. Consulta @fastify/ajv-compiler para ver las opciones.
¿Puedo omitir la validación en desarrollo?
No recomendado. Usa esquemas más flexibles para rutas solo de desarrollo si es necesario, pero mantén la validación en los endpoints públicos.
¿Cómo funcionan las cargas de archivos con esquemas?
Multipart usa @fastify/multipart con validación separada. El Esquema JSON no cubre los campos de archivo.
¿Debo validar los cuerpos de respuesta?
Sí, para las API públicas. Garantiza el cumplimiento del contrato y permite una serialización rápida.
¿Cómo se compara esto con NestJS ValidationPipe?
NestJS usa decoradores de class-validator. Fastify usa Esquema JSON a nivel de ruta. Ambos validan antes de la ejecución del manejador.
Relacionado
- Conceptos básicos de Fastify - para empezar
- Plugins de Fastify - registro de esquemas compartidos
- Zod en los límites - alternativa a Zod
- OpenAPI y Swagger - documentación de API
- Mejores prácticas de Fastify - lista de verificación de la sección
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.