draft-07 ou 2020-12
Resumo: 2020-12 é o atual e adiciona `$defs`, `prefixItems` e `unevaluatedProperties`, mas muitas ferramentas ainda falam apenas draft-07. Escolha pelo que toda a sua cadeia de ferramentas suporta.

Resumo da ópera: use 2020-12 para projetos novos, recue para draft-07 no momento em que qualquer validador, gerador de código ou ferramenta OpenAPI só o suportar, e sempre fixe o draft com $schema.
Resposta curta: 2020-12 para trabalho novo, draft-07 quando um componente antigo obriga.
Linha do tempo
| Draft | Ano | Destaque |
|---|---|---|
| draft-04 | 2013 | id em vez de $id; ainda comum em APIs mais antigas |
| draft-06 | 2017 | const, propertyNames |
| draft-07 | 2018 | if/then/else, readOnly, contentMediaType; melhor compatibilidade |
| 2019-09 | 2019 | $defs substitui definitions, unevaluatedProperties |
| 2020-12 | 2020 | prefixItems, $dynamicRef; recomendação atual |
O que o 2020-12 melhora
Tuplas de array deixam de ser um caso especial. O draft-07 expressa "primeiro elemento é A, segundo é B" com items: [{...}, {...}] mais additionalItems. O 2020-12 usa prefixItems para schemas específicos por posição e items para o resto.
$defs é o nome padrão. Ferramentas escritas depois de 2019 procuram lá por padrão.
unevaluatedProperties funciona com composição. Com allOf, additionalProperties: false rejeita campos definidos por ramos irmãos. unevaluatedProperties: false só considera propriedades realmente avaliadas pelo schema inteiro, que é o que a composição precisa.
Quando draft-07 é a resposta certa
| Situação | Motivo |
|---|---|
| OpenAPI 3.0 | Seu objeto de schema é um subconjunto draft-04/07 |
| Validadores mais antigos (ajv 6, algumas bibliotecas Java) | Eles não conhecem prefixItems nem $dynamicRef |
| Plataforma impõe uma versão | Algumas plataformas low-code e gateways a fixam |
| Geradores de código que param no draft-07 | Palavras-chave desconhecidas são ignoradas silenciosamente |
Teste o último caso diretamente: entregue um schema prefixItems ao seu validador. Se ele passar sem reclamar em vez de relatar uma palavra-chave desconhecida, ele está ignorando a restrição — o desfecho mais perigoso de todos.
Misturando versões
Sempre declare $schema. Os padrões diferem: o ajv assume draft-07, várias bibliotecas Python assumem 2020-12. O mesmo arquivo então valida de forma diferente em dois lugares.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/order.json",
"type": "object"
}
Não faça $ref entre drafts. O comportamento é indefinido.
Atualize em lotes. Dois drafts em um repositório transforma "quais regras se aplicam aqui" em conhecimento tácito.
Perguntas frequentes
Como verifico se meu validador suporta 2020-12?
Entregue ao validador um schema que use prefixItems. Um erro de palavra-chave desconhecida significa que ele não suporta o draft; passar silenciosamente significa que ele está ignorando a restrição, o que é pior.
Por que um projeto deve usar um único draft?
Dois drafts em um repositório transforma "quais regras se aplicam aqui" em conhecimento tácito. Atualize em lotes para que todo arquivo compartilhe a mesma interpretação.
Devo sempre declarar $schema?
Sim. Os padrões diferem: o ajv assume draft-07 enquanto várias bibliotecas Python assumem 2020-12, então o mesmo arquivo pode validar de forma diferente em dois lugares.