JSON Schema: What It Is and How to Use It

Learn JSON Schema from scratch. Understand types, constraints, composition keywords, $ref, and see a complete practical example for API validation.

Equipe JSONTechFebruary 1, 202511 min read

O Que É JSON Schema?

JSON Schema é um vocabulário que permite descrever a estrutura dos dados JSON. Pense nisso como um contrato: ele define quais campos um documento JSON deve ter, quais tipos esses campos devem ser e quais restrições devem ser atendidas. Quando um documento está em conformidade com seu esquema, ele é válido. Quando não está, um validador informa exatamente o que deu errado.

Isso é importante porque o JSON em si é estruturalmente permissivo. Nada na especificação JSON impede uma API de retornar uma string onde você espera um número ou omitir um campo obrigatório. O JSON Schema fecha essa lacuna.

Por Que o JSON Schema É Importante

  • Contratos de API. Defina exatamente o que sua API espera e retorna. Tanto as equipes de cliente quanto de servidor podem validar cargas úteis de forma independente.
  • Validação de dados. Capture dados malformados na fronteira — em envios de formulários, cargas úteis de webhook, arquivos de configuração ou gravações em banco de dados.
  • Documentação. Um esquema é uma documentação legível por máquina. Ferramentas podem gerar documentos legíveis por humanos, formulários e até dados simulados a partir dele.
  • Geração de código. Gere interfaces TypeScript, structs Go ou dataclasses Python diretamente do seu esquema.

O Básico: Tipo, Propriedades, Obrigatório

Todo JSON Schema começa com type. Isso informa ao validador que tipo de valor esperar no nível superior:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "O nome completo do usuário"
    },
    "age": {
      "type": "integer",
      "description": "Idade em anos"
    }
  },
  "required": ["name"]
}

Este esquema diz: "Eu espero um objeto JSON com uma propriedade name (string, obrigatória) e uma propriedade age opcional (inteiro)." Qualquer objeto que não contenha name ou forneça um name não-string é inválido.

Todos os Tipos de JSON Schema

O JSON Schema suporta sete tipos primitivos. Aqui está cada um com um exemplo de esquema mínimo:

TipoValores VálidosExemplo de Esquema
string"hello", ""{"type": "string"}
number3.14, -1, 0{"type": "number"}
integer42, -7{"type": "integer"}
booleantrue, false{"type": "boolean"}
nullnull{"type": "null"}
object{"key": "value"}{"type": "object", "properties": {...}}
array[1, 2, 3]{"type": "array", "items": {...}}

Objetos em Detalhe

Use properties para definir campos esperados, required para listar os obrigatórios e additionalProperties para controlar se campos extras são permitidos:

{
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "email": { "type": "string", "format": "email" }
  },
  "required": ["id", "email"],
  "additionalProperties": false
}

Definir additionalProperties: false rejeita qualquer objeto que contenha chaves não listadas em properties. Isso é útil para contratos de API rigorosos.

Arrays em Detalhe

Use items para definir como cada elemento deve ser, e minItems / maxItems para restringir o comprimento:

{
  "type": "array",
  "items": { "type": "string" },
  "minItems": 1,
  "maxItems": 10,
  "uniqueItems": true
}

Isso aceita um array de 1 a 10 strings únicas. Um array vazio ou um array com duplicatas falharia na validação.

Restrições e Palavras-Chave de Validação

Além dos tipos básicos, o JSON Schema fornece restrições detalhadas para cada tipo:

Restrições de String

Palavra-ChaveDescriçãoExemplo
minLengthNúmero mínimo de caracteres"minLength": 1
maxLengthNúmero máximo de caracteres"maxLength": 255
patternRegex que a string deve corresponder"pattern": "^[A-Z]{2}\\\\d{4}$"
formatDica de formato semântico"format": "email"
enumValores permitidos"enum": ["active", "inactive"]

Restrições de Número

Palavra-ChaveDescriçãoExemplo
minimumO valor deve ser >= a este"minimum": 0
maximumO valor deve ser <= a este"maximum": 100
exclusiveMinimumO valor deve ser > a este"exclusiveMinimum": 0
exclusiveMaximumO valor deve ser < a este"exclusiveMaximum": 1000
multipleOfO valor deve ser divisível por este"multipleOf": 0.01

Combinando Esquemas: allOf, anyOf, oneOf, not

As palavras-chave de composição permitem que você construa esquemas complexos a partir de esquemas mais simples:

  • allOf — Os dados devem ser válidos em relação a todos os esquemas listados. Usado para combinar várias restrições ou estender um esquema base.
  • anyOf — Os dados devem ser válidos em relação a pelo menos um dos esquemas listados. Útil para campos que aceitam múltiplos formatos.
  • oneOf — Os dados devem ser válidos em relação a exatamente um dos esquemas listados. Bom para uniões discriminadas.
  • not — Os dados devem não ser válidos em relação ao esquema dado.
{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "type": { "const": "email" },
        "address": { "type": "string", "format": "email" }
      },
      "required": ["type", "address"]
    },
    {
      "type": "object",
      "properties": {
        "type": { "const": "phone" },
        "number": { "type": "string", "pattern": "^\\\\+?[0-9]{7,15}$" }
      },
      "required": ["type", "number"]
    }
  ]
}

Este esquema aceita um contato de email ou um contato telefônico, mas não ambos — uma maneira limpa de modelar uniões marcadas.

Reutilização com $ref

Os esquemas se tornam repetitivos rapidamente. A palavra-chave $ref permite que você faça referência a uma definição reutilizável:

{
  "type": "object",
  "properties": {
    "billing_address": { "$ref": "#/$defs/address" },
    "shipping_address": { "$ref": "#/$defs/address" }
  },
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zip": { "type": "string", "pattern": "^[0-9]{5}(-[0-9]{4})?$" }
      },
      "required": ["street", "city", "zip"]
    }
  }
}

Tanto billing_address quanto shipping_address compartilham a mesma estrutura sem duplicação. A seção $defs (chamada de definitions em rascunhos mais antigos) é o lugar convencional para armazenar esquemas reutilizáveis.

Exemplo Completo: Validação de Registro de Usuário

Aqui está um esquema do mundo real para validar uma carga útil de registro de usuário. Ele usa a maioria dos recursos que cobrimos:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "UserRegistration",
  "description": "Esquema para o endpoint POST /api/register",
  "type": "object",
  "properties": {
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 30,
      "pattern": "^[a-zA-Z0-9_]+$",
      "description": "Nome de usuário alfanumérico, 3-30 caracteres"
    },
    "email": {
      "type": "string",
      "format": "email",
      "maxLength": 254
    },
    "password": {
      "type": "string",
      "minLength": 8,
      "maxLength": 128,
      "description": "Pelo menos 8 caracteres"
    },
    "age": {
      "type": "integer",
      "minimum": 13,
      "maximum": 150
    },
    "role": {
      "type": "string",
      "enum": ["user", "moderator"],
      "default": "user"
    },
    "acceptedTerms": {
      "type": "boolean",
      "const": true
    },
    "tags": {
      "type": "array",
      "items": { "type": "string", "maxLength": 20 },
      "maxItems": 5,
      "uniqueItems": true
    }
  },
  "required": ["username", "email", "password", "acceptedTerms"],
  "additionalProperties": false
}

Observe como cada campo tem restrições claras e aplicáveis. Um validador rejeitará um nome de usuário de 2 caracteres, uma idade abaixo de 13, tags duplicadas ou quaisquer campos extras não listados no esquema.

Experimente você mesmo: Cole qualquer JSON e gere um esquema automaticamente com nosso Gerador de JSON Schema.

JSON Schema no Mundo Real

OpenAPI / Swagger

OpenAPI usa JSON Schema (com algumas extensões) para definir corpos de requisição, formatos de resposta e parâmetros de consulta. Cada bloco schema em uma especificação OpenAPI é um JSON Schema. Se você escreve documentos OpenAPI, já escreve JSON Schema.

Validação de Formulários

Bibliotecas como react-jsonschema-form e ajv (o validador de JSON Schema mais rápido para JavaScript) usam esquemas para gerar e validar formulários em tempo de execução. Defina seu esquema uma vez, e tanto o backend quanto o frontend podem validar de acordo com as mesmas regras.

Esquemas de Banco de Dados

O MongoDB suporta validação de JSON Schema no nível da coleção. Você pode definir um validador $jsonSchema que rejeita qualquer documento que não esteja em conformidade com seu esquema ao inserir ou atualizar.

Arquivos de Configuração

O VS Code, ESLint e muitas outras ferramentas usam JSON Schema para validar seus arquivos de configuração. Aquela autocompletação que você recebe ao editar tsconfig.json? É alimentada por JSON Schema.

Comparação de Versões de Rascunho

O JSON Schema evoluiu através de vários rascunhos. Aqui estão os que você encontrará:

RascunhoAnoPrincipais AdiçõesStatus
Draft-042013Vocabulário central, $ref, tipos básicosLegado (ainda amplamente utilizado)
Draft-062017const, contains, propertyNamesLegado
Draft-072018if/then/else, readOnly, writeOnlyAmplamente suportado
2019-092019$defs, unevaluatedProperties, dependentRequiredSuportado por validadores principais
2020-122020prefixItems (substitui a validação de tuplas), $ref dinâmicoAtual / recomendado

Para novos projetos, use 2020-12. Se você precisar de máxima compatibilidade com ferramentas existentes, Draft-07 é a escolha segura — possui suporte quase universal de bibliotecas.

Erros Comuns a Evitar

  • Esquecer required. Propriedades definidas em properties são opcionais por padrão. Se um campo deve estar presente, liste-o em required.
  • Confundir number e integer. number aceita decimais; integer não. Use integer para IDs, contagens e outros valores inteiros.
  • Restringir demais muito cedo. Comece com o esquema mínimo que captura erros reais. Você sempre pode apertar as restrições mais tarde — afrouxá-las é uma mudança quebradora.
  • Não usar $ref. Duplicar o mesmo sub-esquema em vários lugares é um pesadelo de manutenção. Extraia estruturas compartilhadas em $defs.
  • Ignorar a validação de format. Por padrão, a maioria dos validadores trata format como uma anotação, não como uma restrição. Você precisa habilitar explicitamente a validação de formato (por exemplo, ajv.addFormat() ou passando { validateFormats: true }).

Experimente você mesmo: Gere um esquema a partir de qualquer amostra JSON com nosso Gerador de JSON Schema, e depois personalize as restrições para atender às suas necessidades.

Ferramentas relacionadas