Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

JSON Schema no Node.js

Atualizado em: 7 de outubro de 2026

Terminal Linux usado em desenvolvimento e administração de aplicações Node.js

JSON Schema descreve a estrutura e as regras de documentos JSON. Em aplicações Node.js, ele pode validar requisições, respostas, eventos, configurações e contratos. Um schema bem definido reduz verificações manuais, gera mensagens consistentes e ajuda ferramentas como OpenAPI, Ajv e geradores de tipos.

Schema básico

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/order.json",
  "type": "object",
  "required": ["customerId", "items"],
  "properties": {
    "customerId": {
      "type": "string",
      "format": "uuid"
    },
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "items": {
        "$ref": "#/$defs/item"
      }
    }
  },
  "additionalProperties": false,
  "$defs": {
    "item": {
      "type": "object",
      "required": ["productId", "quantity"],
      "properties": {
        "productId": { "type": "string", "format": "uuid" },
        "quantity": { "type": "integer", "minimum": 1, "maximum": 1000 }
      },
      "additionalProperties": false
    }
  }
}

Ajv

npm install ajv ajv-formats
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv({
  allErrors: true,
  removeAdditional: false,
  useDefaults: false,
  coerceTypes: false,
});
addFormats(ajv);

const validateOrder = ajv.compile(orderSchema);

Compile schemas no startup, não em cada requisição. Falhe cedo se o contrato estiver inválido.

Validando uma requisição

function validateBody(validate) {
  return (req, res, next) => {
    if (!validate(req.body)) {
      res.status(400).json({
        error: 'validation_failed',
        details: validate.errors.map((item) => ({
          path: item.instancePath,
          keyword: item.keyword,
          message: item.message,
        })),
      });
      return;
    }
    next();
  };
}

Não devolva o schema inteiro ou dados sensíveis nos erros.

additionalProperties

false impede campos desconhecidos e detecta erros de digitação. Em APIs públicas, isso pode dificultar evolução se clientes enviarem campos futuros. Defina a política de compatibilidade conscientemente.

Required e nullable

Um campo pode ser opcional, obrigatório ou aceitar null. Para aceitar null:

{
  "type": ["string", "null"]
}

Não confunda ausência com null. Eles podem ter significados diferentes em PATCH.

String

Use minLength, maxLength, pattern e format. Formatos podem exigir plugin e não substituem validação de negócio.

Números

Use integer, minimum, maximum e multipleOf. Valores monetários devem evitar erros de ponto flutuante; prefira centavos inteiros ou decimal adequado.

Arrays

Defina minItems, maxItems e uniqueItems quando necessário. Limites evitam payloads enormes e trabalho excessivo.

oneOf, anyOf e allOf

oneOf exige exatamente uma alternativa válida; anyOf, pelo menos uma; allOf combina regras. Modelos excessivamente complexos podem gerar erros difíceis e validação lenta.

Discriminador

Um campo type pode selecionar variantes:

{
  "oneOf": [
    { "$ref": "#/$defs/cardPayment" },
    { "$ref": "#/$defs/pixPayment" }
  ]
}

Garanta que as variantes sejam mutuamente exclusivas.

if, then e else

Regras condicionais permitem exigir campos conforme outro atributo. Use para estrutura, mas deixe regras de domínio complexas no código.

$ref

Referências reutilizam schemas. Controle URLs e carregamento remoto; não busque um schema arbitrário fornecido pelo usuário.

$id e versionamento

Use IDs estáveis e uma estratégia de versão. Alterar um schema publicado sem mudar a identidade pode quebrar consumidores e caches.

Coerção de tipos

Ajv pode converter strings em números ou booleanos. Isso é conveniente para query strings, mas pode esconder entrada incorreta. Para body JSON, prefira tipos explícitos.

Defaults

Aplicar defaults durante validação modifica o objeto. Documente esse comportamento e não use defaults para campos de segurança como role, tenant ou owner.

removeAdditional

Remover campos silenciosamente pode esconder erro do cliente e permitir confusão. Em APIs, geralmente é melhor rejeitar ou preservar conforme contrato.

Validação de resposta

Validar respostas em testes e staging detecta regressões:

if (!validateResponse(payload)) {
  logger.error({ errors: validateResponse.errors }, 'Resposta fora do contrato');
  throw new InternalError();
}

Em produção, avalie overhead e nunca devolva conteúdo parcial inválido.

Schema de configuração

Valide variáveis processadas no startup:

const config = {
  port: Number(process.env.PORT),
  environment: process.env.NODE_ENV,
};

if (!validateConfig(config)) {
  throw new Error('Configuração inválida');
}

Eventos e filas

Inclua schemaVersion em mensagens. Consumidores devem tratar versões conhecidas e enviar inválidas para dead letter sem loop infinito.

Segurança

Validação de schema não elimina SQL injection, XSS, path traversal ou regras de autorização. Ela garante forma e limites iniciais; o código ainda precisa normalizar e usar APIs seguras.

ReDoS em pattern

Regex complexas em pattern podem consumir CPU. Use expressões simples, limite tamanho da string e teste entradas adversariais.

Mensagens de erro

Traduza erros para um formato estável. O caminho deve apontar o campo, mas não revelar implementação interna ou valores secretos.

TypeScript

Tipos compilados não validam dados externos em runtime. Gere tipos a partir do schema ou schema a partir dos tipos, mas mantenha uma fonte de verdade e teste divergências.

OpenAPI

OpenAPI 3.1 usa vocabulário próximo do JSON Schema. Ainda assim, ferramentas podem suportar subconjuntos diferentes. Execute lint e testes com o ecossistema escolhido.

Erros comuns

  • compilar schema em cada request;
  • sem limites de tamanho;
  • coerção silenciosa;
  • additionalProperties permissivo sem intenção;
  • regex vulnerável;
  • usar tipos TypeScript como validação;
  • buscar referências remotas não confiáveis;
  • schema e OpenAPI divergentes;
  • expor valores nos erros.

Fluxo recomendado

  1. escolha o draft;
  2. defina IDs e versões;
  3. aplique limites;
  4. compile no startup;
  5. valide entrada na borda;
  6. mantenha coerção explícita;
  7. teste schemas de resposta;
  8. integre ao OpenAPI;
  9. monitore falhas.

Combine JSON Schema com OpenAPI no Node.js, Zod no TypeScript, Tratamento de Erros e Rate Limiting.

Consulte a especificação oficial JSON Schema e a documentação oficial do Ajv.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita