Validação JSON Schema: Dados, Documentação e Código

JSON Schema: O Contrato dos Dados

JSON Schema é a linguagem de definição de estrutura para dados JSON — semelhante ao TypeScript para JavaScript, mas aplicável à validação em tempo de execução e cenários multilinguagem.

Uso Descrição
Validação de dados Validação de requisições/respostas de API
Geração de documentação Geração automática de documentação de API
Sugestões do IDE Autocompletar inteligente no VS Code
Dados Mock Geração automática de dados de teste
Validação de configuração package.json, tsconfig.json, etc.

I. Tipos Básicos

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 1, "maxLength": 100 },
    "age": { "type": "integer", "minimum": 0, "maximum": 150 },
    "email": { "type": "string", "format": "email" },
    "isActive": { "type": "boolean" },
    "score": { "type": "number", "minimum": 0, "maximum": 100 },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1,
      "maxItems": 10,
      "uniqueItems": true
    }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}

Formatos Integrados

format Regra de Correspondência Exemplo
email RFC 5322 user@example.com
uri URI https://example.com
date Data ISO 8601 2026-06-02
time Hora ISO 8601 14:30:00
date-time Data e hora ISO 8601 2026-06-02T14:30:00Z
ipv4 Endereço IPv4 192.168.1.1
ipv6 Endereço IPv6 ::1
uuid UUID 550e8400-e29b-41d4-a716-446655440000
hostname Nome do host example.com

II. Padrões Avançados

Objetos Aninhados

{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "profile": {
          "type": "object",
          "properties": {
            "avatar": { "type": "string", "format": "uri" },
            "bio": { "type": "string", "maxLength": 200 }
          }
        }
      }
    }
  }
}

Enumerações e Tipos de União

{
  "status": {
    "type": "string",
    "enum": ["pending", "active", "completed", "cancelled"]
  },
  "id": {
    "oneOf": [
      { "type": "string", "format": "uuid" },
      { "type": "integer", "minimum": 1 }
    ]
  }
}

Validação Condicional

{
  "type": "object",
  "properties": {
    "paymentMethod": { "type": "string", "enum": ["credit_card", "bank_transfer"] },
    "cardNumber": { "type": "string" },
    "bankAccount": { "type": "string" }
  },
  "if": {
    "properties": { "paymentMethod": { "const": "credit_card" } }
  },
  "then": {
    "required": ["cardNumber"],
    "properties": { "cardNumber": { "pattern": "^\\d{16}$" } }
  },
  "else": {
    "required": ["bankAccount"]
  }
}

Padrões de Expressão Regular

{
  "phone": { "type": "string", "pattern": "^1[3-9]\\d{9}$" },
  "postalCode": { "type": "string", "pattern": "^\\d{6}$" },
  "slug": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
}

III. $ref e Reutilização de Definições

{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zipCode": { "type": "string", "pattern": "^\\d{6}$" }
      },
      "required": ["street", "city", "zipCode"]
    }
  },
  "type": "object",
  "properties": {
    "homeAddress": { "$ref": "#/$defs/address" },
    "workAddress": { "$ref": "#/$defs/address" }
  }
}

IV. Validação em Tempo de Execução

Ajv (o validador mais rápido)

import Ajv from 'ajv';

const ajv = new Ajv({ allErrors: true, strict: false });

const schema = {
  type: 'object',
  properties: {
    name: { type: 'string', minLength: 1 },
    age: { type: 'integer', minimum: 0 },
  },
  required: ['name', 'age'],
};

const validate = ajv.compile(schema);

const valid = validate({ name: '张三', age: 25 });
if (!valid) {
  console.log(validate.errors);
  // [{ keyword: 'minimum', dataPath: '/age', message: 'must be >= 0' }]
}

Zod (TypeScript primeiro)

import { z } from 'zod';

const UserSchema = z.object({
  name: z.string().min(1).max(100),
  age: z.number().int().min(0).max(150),
  email: z.string().email(),
  tags: z.array(z.string()).min(1).max(10),
});

// Inferência automática de tipos
type User = z.infer<typeof UserSchema>;

// Validação
const result = UserSchema.safeParse(input);
if (result.success) {
  console.log(result.data); // Tipo seguro
} else {
  console.log(result.error.issues);
}

V. Sugestões Inteligentes do IDE

Configuração do VS Code

// .vscode/settings.json
{
  "json.schemas": [
    {
      "fileMatch": ["/config/*.json"],
      "url": "./schemas/config-schema.json"
    },
    {
      "fileMatch": ["package.json"],
      "url": "https://json.schemastore.org/package"
    }
  ]
}

Referenciar Schema em Arquivos JSON

{
  "$schema": "./schemas/config-schema.json",
  "name": "my-project"
  // Autocompletar do IDE, indicações de erros
}

Schema Store

Schema Store fornece mais de 400 JSON Schemas comuns:

  • package.json
  • tsconfig.json
  • .eslintrc.json
  • docker-compose.json
  • GitHub Actions workflows

VI. Gerar Schema a Partir do JSON

Uso de Ferramentas

  1. Abra a Ferramenta de Formatação JSON
  2. Cole os dados JSON
  3. Clique em "Gerar Schema"
  4. Inferência automática de tipos, enumerações e intervalos

Ferramentas de Linha de Comando

# Usar json-schema-generator
npx json-schema-generator sample.json -o schema.json

# Usar quicktype
npx quicktype sample.json -o schema.json --lang schema

VII. Geração de Dados Mock

import { faker } from '@faker-js/faker';

// Gerar dados Mock baseados no Schema
function generateMock(schema) {
  if (schema.type === 'string') {
    if (schema.format === 'email') return faker.internet.email();
    if (schema.format === 'uri') return faker.internet.url();
    if (schema.enum) return faker.helpers.arrayElement(schema.enum);
    return faker.lorem.word();
  }
  if (schema.type === 'integer') return faker.number.int(schema);
  if (schema.type === 'boolean') return faker.datatype.boolean();
  if (schema.type === 'array') {
    return Array.from({ length: 3 }, () => generateMock(schema.items));
  }
  if (schema.type === 'object') {
    const result = {};
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      result[key] = generateMock(propSchema);
    }
    return result;
  }
}

VIII. Melhores Práticas

  1. Sempre declarar $schema: Especificar a versão Draft para evitar ambiguidades
  2. Usar additionalProperties: false: Proibir campos não definidos
  3. Usar $defs + $ref: Reutilizar estruturas comuns
  4. Usar format em vez de escrever pattern manualmente: Mais legível, o validador trata automaticamente
  5. Integrar validação no CI: Garantir que as respostas da API sempre estejam em conformidade com o Schema
  6. Gerenciar versões do Schema: Sincronizar com as versões da API, suportar verificação de compatibilidade retroativa
#JSON Schema#数据校验#Ajv#Zod#API