Validação com JSON Schema: O Guia Definitivo
JSON Schema é um vocabulário para anotar e validar documentos JSON. Ele fornece um contrato para seus dados — definindo qual formato devem ter, quais tipos são aceitáveis e quais campos são obrigatórios. Se você trabalha com APIs, arquivos de configuração ou qualquer dado estruturado, JSON Schema é uma ferramenta essencial no seu arsenal.
Por Que Usar JSON Schema?
Sem validação, dados JSON são uma incógnita. Você pode receber um campo de idade como string, um email faltando ou uma data no formato errado. JSON Schema captura esses problemas na fronteira, antes que dados incorretos se propaguem pelo seu sistema.
Principais benefícios:
- Aplicação de contratos de API: Valide corpos de requisição e resposta automaticamente
- Documentação: O schema serve como documentação viva das suas estruturas de dados
- Geração de código: Ferramentas podem gerar tipos, formulários e schemas de banco de dados a partir do JSON Schema
- Testes: Valide fixtures de teste e dados mock contra o schema
Estrutura Básica do Schema
Todo JSON Schema começa com algumas propriedades padrão:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.schema.json",
"title": "User",
"description": "A registered user in the system",
"type": "object",
"properties": {
"id": { "type": "integer", "minimum": 1 },
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 }
},
"required": ["id", "name", "email"]
}
Use nosso Formatador JSON para embelezar seus schemas e facilitar a leitura antes de compartilhar com sua equipe.
Restrições de Tipo
JSON Schema suporta seis tipos primitivos:
| Tipo | Descrição | Exemplo |
|---|---|---|
string | Dados de texto | "hello" |
number | Qualquer valor numérico | 3.14 |
integer | Apenas números inteiros | 42 |
boolean | Verdadeiro ou falso | true |
array | Lista ordenada | [1, 2, 3] |
object | Pares chave-valor | {"key": "value"} |
null | Valor nulo | null |
Restrições de String
{
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[A-Za-z0-9]+$",
"format": "email"
}
Formatos integrados incluem: email, uri, date, date-time, ipv4, ipv6, uuid e hostname.
Restrições Numéricas
{
"type": "number",
"minimum": 0,
"maximum": 100,
"exclusiveMinimum": 0,
"multipleOf": 0.01
}
Validação de Arrays
Arrays podem ser validados quanto a seus itens, comprimento e unicidade:
{
"type": "array",
"items": { "type": "string", "format": "email" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
Para validação de tuplas (arrays de comprimento fixo com tipos específicos por posição):
{
"type": "array",
"prefixItems": [
{ "type": "number" },
{ "type": "string" },
{ "type": "boolean" }
],
"items": false
}
Validação de Objetos
Objetos suportam validação de propriedades, campos obrigatórios e controle de propriedades adicionais:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"role": { "enum": ["admin", "editor", "viewer"] }
},
"required": ["name", "role"],
"additionalProperties": false
}
Definir additionalProperties como false é um modo estrito que rejeita quaisquer propriedades não definidas no schema. Isso é particularmente útil para APIs onde você deseja capturar erros de digitação nos nomes dos campos.
Palavras-chave de Composição
JSON Schema suporta a combinação de schemas usando operadores lógicos:
allOf (E)
Os dados devem ser válidos contra todos os subschemas:
{
"allOf": [
{ "$ref": "#/$defs/baseUser" },
{ "properties": { "role": { "const": "admin" } } }
]
}
oneOf (OU Exclusivo)
Os dados devem ser válidos contra exatamente um dos subschemas:
{
"oneOf": [
{ "properties": { "type": { "const": "email" }, "email": { "type": "string" } } },
{ "properties": { "type": { "const": "phone" }, "phone": { "type": "string" } } }
]
}
anyOf (OU)
Os dados devem ser válidos contra pelo menos um dos subschemas.
Validação Condicional
As palavras-chave if/then/else permitem validação condicional:
{
"type": "object",
"properties": {
"country": { "type": "string" },
"postalCode": { "type": "string" }
},
"if": {
"properties": { "country": { "const": "US" } }
},
"then": {
"properties": { "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" } }
},
"else": {
"properties": { "postalCode": { "pattern": "^[A-Z0-9 -]+$" } }
}
}
Referências e Reutilização
Use $ref para referenciar definições reutilizáveis:
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"country": { "type": "string" }
},
"required": ["street", "city", "country"]
}
},
"type": "object",
"properties": {
"billingAddress": { "$ref": "#/$defs/address" },
"shippingAddress": { "$ref": "#/$defs/address" }
}
}
Validação na Prática
JavaScript (Ajv)
const Ajv = require('ajv');
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) console.log(validate.errors);
Python (jsonschema)
from jsonschema import validate, ValidationError
try:
validate(instance=data, schema=schema)
except ValidationError as e:
print(f"Validation error: {e.message}")
Para validação rápida sem configurar um ambiente de desenvolvimento, cole seu JSON e schema no nosso Validador JSON.
Exemplo do Mundo Real: Schema de Resposta de API
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"status": { "enum": ["success", "error"] },
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"createdAt": { "type": "string", "format": "date-time" }
},
"required": ["id", "name"]
}
},
"pagination": {
"type": "object",
"properties": {
"page": { "type": "integer", "minimum": 1 },
"perPage": { "type": "integer", "minimum": 1, "maximum": 100 },
"total": { "type": "integer", "minimum": 0 }
}
}
},
"required": ["status", "data"]
}
FAQ
Qual é a diferença entre JSON Schema draft-07 e 2020-12?
O Draft 2020-12 introduziu diversas melhorias: prefixItems substituiu a forma de tupla do items, $dynamicRef permite referências mais flexíveis, e o suporte a vocabulários permite extensões personalizadas. Para novos projetos, use 2020-12. Para compatibilidade com ferramentas mais antigas, o draft-07 ainda tem amplo suporte.
JSON Schema pode validar JSON aninhado dentro de um campo string?
Não diretamente. JSON Schema valida a estrutura de JSON já parseado. Se um campo contém uma string JSON, você precisaria parseá-la primeiro e validar separadamente. Alguns validadores oferecem validadores de formato personalizados que podem lidar com isso, mas não faz parte do padrão.
Recursos Relacionados
- Formatador JSON — Formate e embeleze seus schemas JSON
- Como Validar JSON — Erros comuns de validação JSON e correções
- Padrões de Design de APIs JSON — Construindo APIs REST melhores com JSON