Introdução
Se o JSON dominou a comunicação entre sistemas nos últimos 20 anos, o TOON Protocol tenta resolver suas limitações mais profundas: falta de tipagem forte, ausência de validação nativa e dificuldade de documentar regras sobre cada campo.
Escrever um TOON Schema significa criar um documento que combina dados + tipos + validação + semântica em um único arquivo legível. Isso reduz erros, aumenta segurança e facilita integração entre times e linguagens.
Este guia mostra, passo a passo, como criar seu primeiro schema.
1. Estrutura básica de um documento TOON
A sintaxe do TOON lembra YAML, mas com anotações de tipos usando ::.
Exemplo mínimo:
user:
name: "Rafael Lins" :: string(required)
age: 34 :: int(min=0, max=120)
email: "rafael@adrock.com.br" :: email(required)
user:
name: "Rafael Lins" :: string(required)
age: 34 :: int(min=0, max=120)
email: "rafael@adrock.com.br" :: email(required)
user:
name: "Rafael Lins" :: string(required)
age: 34 :: int(min=0, max=120)
email: "rafael@adrock.com.br" :: email(required)
Regras básicas:
tudo é indentado como YAML
valores vêm primeiro, tipagem depois (valor :: tipo)
cada campo pode ter múltiplos constraints
nada é inferido automaticamente
O TOON é explícito e determinístico.
2. Tipos essenciais do TOON
Os tipos principais:
string
int
float
bool
email
url
datetime
list(tipo)
object
enum(…)
Exemplos:
price: 199.90 :: float(min=0)
isActive: true :: bool
site: "https://adrock.com.br" :: url
role: "admin" :: enum("admin", "editor", "viewer")price: 199.90 :: float(min=0)
isActive: true :: bool
site: "https://adrock.com.br" :: url
role: "admin" :: enum("admin", "editor", "viewer")price: 199.90 :: float(min=0)
isActive: true :: bool
site: "https://adrock.com.br" :: url
role: "admin" :: enum("admin", "editor", "viewer")3. Criando listas e objetos aninhados
Lista simples:
tags: ["seo", "analytics", "python"] :: list(string)
tags: ["seo", "analytics", "python"] :: list(string)
tags: ["seo", "analytics", "python"] :: list(string)
Lista com validação:
scores: [10, 9, 8] :: list(int(min=0, max=10))
scores: [10, 9, 8] :: list(int(min=0, max=10))
scores: [10, 9, 8] :: list(int(min=0, max=10))
Objeto aninhado:
address:
street: "Rua X" :: string(required)
number: 120 :: int(min=1)
city: "Curitiba" :: string
zip: "80000-000" :: string(pattern="[0-9]{5}-[0-9]{3}")address:
street: "Rua X" :: string(required)
number: 120 :: int(min=1)
city: "Curitiba" :: string
zip: "80000-000" :: string(pattern="[0-9]{5}-[0-9]{3}")address:
street: "Rua X" :: string(required)
number: 120 :: int(min=1)
city: "Curitiba" :: string
zip: "80000-000" :: string(pattern="[0-9]{5}-[0-9]{3}")Objetos TOON funcionam como dicionários fortemente tipados.
4. Campos obrigatórios, opcionais e nullables
Um dos pontos fortes do TOON é a clareza sobre o que é opcional ou obrigatório.
Campo obrigatório:
email: "client@example.com" :: email(required)
email: "client@example.com" :: email(required)
email: "client@example.com" :: email(required)
Campo opcional:
nickname: null :: string(optional)
nickname: null :: string(optional)
nickname: null :: string(optional)
Aceitando null explicitamente:
middleName: null :: string(nullable)
middleName: null :: string(nullable)
middleName: null :: string(nullable)
Diferente do JSON, null, “campo vazio” e “campo ausente” são INEQUIVOCAMENTE diferentes.
5. Validação embutida no próprio schema
O TOON traz validações comuns:
min
max
length
pattern
enum()
required
optional
nullable
Exemplos completos:
person:
name: "Rafael" :: string(required, length(min=2, max=50))
age: 34 :: int(min=0, max=150)
salary: 5000 :: float(min=0)
phone: "+55 41 99999-0000" :: string(pattern="^\+55")
person:
name: "Rafael" :: string(required, length(min=2, max=50))
age: 34 :: int(min=0, max=150)
salary: 5000 :: float(min=0)
phone: "+55 41 99999-0000" :: string(pattern="^\+55")
person:
name: "Rafael" :: string(required, length(min=2, max=50))
age: 34 :: int(min=0, max=150)
salary: 5000 :: float(min=0)
phone: "+55 41 99999-0000" :: string(pattern="^\+55")
As validações tornam o documento auto descritivo — não há risco de “documentação desatualizada”.
6. Como estruturar um TOON Schema completo
Aqui está um schema realista:
order:
id: "ORD-2025-0001" :: string(required, pattern="^ORD-[0-9]{4}-[0-9]{4}$")
createdAt: "2025-10-12T14:30:00Z" :: datetime(required)
total: 499.90 :: float(min=0)
customer:
name: "Ana Souza" :: string(required)
email: "ana@example.com" :: email(required)
phone: "+55 11 90000-0000" :: string(pattern="^\+55")
items:
- sku: "LED-123" :: string
quantity: 2 :: int(min=1)
price: 199.90 :: float(min=0)
- sku: "LED-555" :: string
quantity: 1 :: int(min=1)
price: 99.90 :: float(min=0)
status: "pending" :: enum("pending", "paid", "shipped", "canceled")order:
id: "ORD-2025-0001" :: string(required, pattern="^ORD-[0-9]{4}-[0-9]{4}$")
createdAt: "2025-10-12T14:30:00Z" :: datetime(required)
total: 499.90 :: float(min=0)
customer:
name: "Ana Souza" :: string(required)
email: "ana@example.com" :: email(required)
phone: "+55 11 90000-0000" :: string(pattern="^\+55")
items:
- sku: "LED-123" :: string
quantity: 2 :: int(min=1)
price: 199.90 :: float(min=0)
- sku: "LED-555" :: string
quantity: 1 :: int(min=1)
price: 99.90 :: float(min=0)
status: "pending" :: enum("pending", "paid", "shipped", "canceled")order:
id: "ORD-2025-0001" :: string(required, pattern="^ORD-[0-9]{4}-[0-9]{4}$")
createdAt: "2025-10-12T14:30:00Z" :: datetime(required)
total: 499.90 :: float(min=0)
customer:
name: "Ana Souza" :: string(required)
email: "ana@example.com" :: email(required)
phone: "+55 11 90000-0000" :: string(pattern="^\+55")
items:
- sku: "LED-123" :: string
quantity: 2 :: int(min=1)
price: 199.90 :: float(min=0)
- sku: "LED-555" :: string
quantity: 1 :: int(min=1)
price: 99.90 :: float(min=0)
status: "pending" :: enum("pending", "paid", "shipped", "canceled")Compare o mesmo documento em JSON:
{
"order": {
"id": "ORD-2025-0001",
"createdAt": "2025-10-12T14:30:00Z",
"total": 499.90,
"customer": {
"name": "Ana Souza",
"email": "ana@example.com",
"phone": "+55 11 90000-0000"
},
"items": [
{
"sku": "LED-123",
"quantity": 2,
"price": 199.90
}
],
"status": "pending"
}
}{
"order": {
"id": "ORD-2025-0001",
"createdAt": "2025-10-12T14:30:00Z",
"total": 499.90,
"customer": {
"name": "Ana Souza",
"email": "ana@example.com",
"phone": "+55 11 90000-0000"
},
"items": [
{
"sku": "LED-123",
"quantity": 2,
"price": 199.90
}
],
"status": "pending"
}
}{
"order": {
"id": "ORD-2025-0001",
"createdAt": "2025-10-12T14:30:00Z",
"total": 499.90,
"customer": {
"name": "Ana Souza",
"email": "ana@example.com",
"phone": "+55 11 90000-0000"
},
"items": [
{
"sku": "LED-123",
"quantity": 2,
"price": 199.90
}
],
"status": "pending"
}
}O JSON é mais curto, porém não tem:
tipo
validação
constraints
enum
coerção semântica
auditoria
garantia de integridade
O TOON entrega tudo isso no arquivo.
7. Como validar um arquivo TOON
Embora os parsers ainda estejam evoluindo, a lógica típica é:
valor → tipo → constraints → resultado
valor → tipo → constraints → resultado
valor → tipo → constraints → resultado
Erros comuns:
tipo incompatível
pattern inválido
enum não permitido
campo obrigatório ausente
constraints violadas
O parser (dependendo da biblioteca) retorna erros estruturados.
8. TOON + Python / Node.js / Go (cenários futuros)
Ainda não existem SDKs oficiais maduros, mas a comunidade já discute:
transformar TOON em modelos Pydantic
gerar interfaces TypeScript automaticamente
converter TOON para Protobuf
usar TOON como contrato de API em OpenAPI 4.0
uso em LLMs para garantir respostas tipadas
Quando surgirem ferramentas estáveis, TOON pode se tornar o “schema universal” de APIs modernas.
9. Boas práticas ao escrever seu primeiro schema
Seja explícito sempre.
Nunca deixe o parser inferir nada.
Valide o que importa.
Defina min/max, enum, pattern.
Use tipagem forte.
Evite aninhamento profundo.
Mantenha coerência entre schemas.
Documente regras críticas dentro do próprio arquivo.
Trate null corretamente.
Prefira enums a strings soltas.
10. Template pronto para iniciar seu próprio TOON Schema
Copie e personalize:
entity:
id: "" :: string(required)
createdAt: "" :: datetime(required)
meta:
version: 1 :: int(min=1)
source: "" :: string(optional)
data:
# Adicione aqui seus campos
example: "" :: string(optional)entity:
id: "" :: string(required)
createdAt: "" :: datetime(required)
meta:
version: 1 :: int(min=1)
source: "" :: string(optional)
data:
# Adicione aqui seus campos
example: "" :: string(optional)entity:
id: "" :: string(required)
createdAt: "" :: datetime(required)
meta:
version: 1 :: int(min=1)
source: "" :: string(optional)
data:
# Adicione aqui seus campos
example: "" :: string(optional)Referências e análises técnicas
👉 https://json.org
👉 https://json-schema.org
👉 https://yaml.org
👉 https://protobuf.dev
👉 https://avro.apache.org
👉 RFCs sobre schema-driven contracts
👉 Discussões técnicas no GitHub sobre novos formatos estruturados