Validação com JSON Schema
Use o JSON Schema integrado do Fastify para validação de requisições e serialização compilada de respostas.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
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 });
});Quando usar isso: Todos os endpoints de API públicos. A validação de schema é a principal vantagem do Fastify sobre o Express.
Exemplo de Trabalho
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: "Falha na validação", details: err.validation });
}
reply.status(500).send({ error: "Erro interno do servidor" });
});O que isso demonstra:
- Schemas TypeBox com inferência de tipo TypeScript
- Erro 400 automático em falha de validação
- Manipulador de erro personalizado para o formato do erro de validação
- Schema de resposta compila o serializador para velocidade
Mergulho Profundo
Como Funciona
- O Fastify usa o Ajv para validação de requisições no momento do registro da rota.
- Schemas de resposta compilam para funções de serialização rápidas (fast-json-stringify).
- A validação ocorre no hook
preValidationantes do manipulador. - Respostas inválidas em desenvolvimento geram avisos; em produção, são removidas para corresponder ao schema.
Cobertura de Schema
| Parte | Valida | Status de Falha |
|---|---|---|
body | Corpo POST/PUT/PATCH | 400 |
querystring | Parâmetros de query da URL | 400 |
params | Parâmetros de rota (:id) | 400 |
headers | Cabeçalhos da requisição | 400 |
response | Valor de retorno do manipulador | 500 (serialização) |
Schemas Reutilizáveis
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 }));Armadilhas
- Sem schema de resposta - perde o benefício da velocidade de serialização. Correção: defina schemas de resposta para todos os endpoints públicos.
additionalPropertiesexcessivamente permissivo - aceita campos inesperados. Correção: definaadditionalProperties: falseem objetos.- Schema e tipos TypeScript divergem - o runtime valida uma forma, o TS assume outra. Correção: use o TypeBox ou o provedor de tipo Zod.
- Schemas aninhados complexos lentos na compilação - o tempo de inicialização aumenta. Correção: reutilize schemas com
$refeaddSchema. - Retornando campos que não estão no schema de resposta - são removidos silenciosamente em produção. Correção: combine a saída do manipulador com o schema exatamente.
- Validando com Zod E JSON Schema - custo de validação duplicado. Correção: escolha um; use
fastify-type-provider-zod.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Provedor de tipo Zod | Equipe já padronizada em Zod | Desempenho máximo de serialização (TypeBox/JSON Schema é mais rápido) |
| Ajv standalone no Express | Preso no Express | Iniciando um novo projeto Fastify |
| Geração de código OpenAPI | Contrato primeiro com consumidores externos | API apenas interna |
| Validação manual no manipulador | Apenas protótipo rápido | Qualquer endpoint de produção |
FAQs
A validação deixa as requisições lentas?
A validação adiciona microssegundos. Serializadores compilados aceleram as respostas, muitas vezes resultando em um ganho de desempenho em comparação com JSON.stringify.
Posso gerar OpenAPI a partir de schemas?
Sim. @fastify/swagger lê os schemas de rota e gera automaticamente a documentação OpenAPI 3.
Como valido campos opcionais?
Omita do array required. Use { type: ["string", "null"] } para campos anuláveis.
Qual rascunho do JSON Schema o Fastify usa?
O Fastify 5 usa Ajv com JSON Schema draft-07 por padrão. Verifique @fastify/ajv-compiler para opções.
Posso pular a validação em desenvolvimento?
Não recomendado. Use schemas mais flexíveis para rotas apenas de desenvolvimento, se necessário, mas mantenha a validação em endpoints públicos.
Como funcionam os uploads de arquivos com schemas?
Multipart usa @fastify/multipart com validação separada. JSON Schema não cobre campos de arquivo.
Devo validar corpos de resposta?
Sim, para APIs públicas. Garante a conformidade do contrato e permite serialização rápida.
Como isso se compara ao NestJS ValidationPipe?
O NestJS usa decoradores class-validator. O Fastify usa JSON Schema no nível da rota. Ambos validam antes da execução do manipulador.
Relacionados
- Fastify Basics - começando
- Fastify Plugins - registro de schema compartilhado
- Zod at Boundaries - alternativa Zod
- OpenAPI and Swagger - documentação de API
- Fastify Best Practices - checklist da seção
Versões do Stack: Esta página foi escrita para Node.js 24.18.0 (LTS Ativo), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.