Esquemas JSON (Schemas)
📚 Índice
- Introdução
- O que são JSON Schemas
- Por que Usar Schemas
- JSON Schema no Document Hub
- Criar/Atualizar Schemas
- Obter Schemas
- Deletar Schemas
- Validação Automática
- Exemplos Práticos
- JSON Schema Reference
- Casos de Uso Avançados
- Boas Práticas
- Troubleshooting
Introdução
Schemas JSON permitem definir a estrutura, tipo de dados e regras de validação para seus documentos. O Document Hub suporta JSON Schema Draft 4 e superior.
Escopo Necessário
Para gerenciar schemas, você precisa de um token com o escopo schema:manage.
O que são JSON Schemas
JSON Schema é um padrão para descrever e validar a estrutura de dados JSON. Ele define:
- ✅ Tipos de dados permitidos (string, number, object, array, etc.)
- ✅ Campos obrigatórios (required)
- ✅ Restrições (min/max, pattern, enum, etc.)
- ✅ Estrutura aninhada (propriedades dentro de objetos)
- ✅ Validações personalizadas
Exemplo Simples
{
"type": "object",
"required": ["name", "email"],
"properties": {
"name": {
"type": "string",
"minLength": 2
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
}
}
}Este schema valida que:
- O documento deve ser um objeto
- Campos
nameeemailsão obrigatórios namedeve ser string com pelo menos 2 caracteresemaildeve ser string em formato de email válidoage(opcional) deve ser inteiro entre 0 e 150
Por que Usar Schemas
Benefícios
-
Consistência de Dados
- Garante que todos os documentos sigam o mesmo formato
- Evita dados malformados ou incompletos
-
Validação Automática
- Rejeita documentos inválidos antes de salvá-los
- Retorna erros descritivos para correção
-
Documentação Viva
- O schema serve como documentação da estrutura esperada
- Outros desenvolvedores entendem o formato rapidamente
-
Segurança
- Previne injeção de campos não esperados
- Valida tipos de dados para evitar problemas de segurança
-
Evolução Controlada
- Permite evolução do formato de dados de forma controlada
- Facilita migrações
JSON Schema no Document Hub
Estrutura do Schema
Schemas são associados a um escopo específico:
Cliente → Ambiente → Contexto → Tipo
Isso significa que você pode ter schemas diferentes para:
- O mesmo tipo em ambientes diferentes
- O mesmo tipo em contextos diferentes
Modelo de Dados
{
"id": 1,
"client_id": "9fc42fe9-a4fd-443c-8d49-b85ece2151b9",
"environment": "production",
"context": "orders",
"type": "invoice",
"schema": {
/* JSON Schema aqui */
},
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}Criar/Atualizar Schemas
Endpoint
POST /api/v1/client/{client}/{environment}/context/{context}/type/{type}/schemaNota: Este endpoint funciona como upsert:
- Se o schema não existe, ele é criado (retorna 201)
- Se o schema existe, ele é atualizado (retorna 200)
Headers Necessários
Authorization: Bearer {SEU_TOKEN}
Content-Type: application/jsonBody da Requisição
{
"schema": {
/* Seu JSON Schema aqui */
}
}Exemplo 1: Schema Simples para Faturas
curl -X POST "https://document-hub-api-xp.wake.tech/api/v1/client/9fc42fe9-a4fd-443c-8d49-b85ece2151b9/production/context/orders/type/invoice/schema" \
-H "Authorization: Bearer {SEU_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"schema": {
"type": "object",
"required": ["customer_id", "amount", "currency", "status"],
"properties": {
"customer_id": {
"type": "string",
"pattern": "^CUST-[0-9]+$"
},
"invoice_number": {
"type": "string"
},
"amount": {
"type": "number",
"minimum": 0
},
"currency": {
"type": "string",
"enum": ["BRL", "USD", "EUR"]
},
"status": {
"type": "string",
"enum": ["pending", "paid", "cancelled"]
},
"issue_date": {
"type": "string",
"format": "date"
},
"due_date": {
"type": "string",
"format": "date"
}
}
}
}'Exemplo 2: Schema com Objetos Aninhados
curl -X POST "https://api.../production/context/orders/type/order/schema" \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"schema": {
"type": "object",
"required": ["customer", "items", "total"],
"properties": {
"customer": {
"type": "object",
"required": ["name", "email"],
"properties": {
"name": {
"type": "string",
"minLength": 2
},
"email": {
"type": "string",
"format": "email"
},
"document": {
"type": "string"
}
}
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["product_id", "quantity", "price"],
"properties": {
"product_id": {
"type": "string"
},
"quantity": {
"type": "integer",
"minimum": 1
},
"price": {
"type": "number",
"minimum": 0
}
}
}
},
"total": {
"type": "number",
"minimum": 0
},
"status": {
"type": "string",
"enum": ["pending", "processing", "shipped", "delivered", "cancelled"]
}
}
}
}'Resposta (201 Created ou 200 OK)
{
"id": 1,
"client_id": "9fc42fe9-a4fd-443c-8d49-b85ece2151b9",
"environment": "production",
"context": "orders",
"type": "invoice",
"schema": {
"type": "object",
"required": ["customer_id", "amount", "currency", "status"],
"properties": { ... }
},
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}Obter Schemas
Endpoint
GET /api/v1/client/{client}/{environment}/context/{context}/type/{type}/schemaExemplo
curl -X GET "https://document-hub-api-xp.wake.tech/api/v1/client/9fc42fe9-a4fd-443c-8d49-b85ece2151b9/production/context/orders/type/invoice/schema" \
-H "Authorization: Bearer {SEU_TOKEN}"Resposta (200 OK)
{
"id": 1,
"client_id": "9fc42fe9-a4fd-443c-8d49-b85ece2151b9",
"environment": "production",
"context": "orders",
"type": "invoice",
"schema": {
"type": "object",
"required": ["customer_id", "amount", "currency", "status"],
"properties": { ... }
},
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}Resposta (404 Not Found)
Se não existe schema para este escopo:
{
"message": "Not Found"
}Deletar Schemas
Endpoint
DELETE /api/v1/client/{client}/{environment}/context/{context}/type/{type}/schemaExemplo
curl -X DELETE "https://document-hub-api-xp.wake.tech/api/v1/client/9fc42fe9-a4fd-443c-8d49-b85ece2151b9/production/context/orders/type/invoice/schema" \
-H "Authorization: Bearer {SEU_TOKEN}"Resposta (204 No Content)
Schema deletado com sucesso. Sem corpo de resposta.
Comportamento
Após deletar o schema:
- ✅ Documentos existentes não são afetados
- ✅ Novos documentos não serão validados (qualquer estrutura aceita)
- ✅ Você pode criar um novo schema a qualquer momento
Validação Automática
Como Funciona
Quando um schema está definido para um tipo de documento:
-
Ao criar um documento (
POST):- O campo
dataé validado contra o schema - Se inválido, retorna erro 422 com detalhes
- O campo
-
Ao atualizar um documento (
PUT):- O campo
dataé validado contra o schema - Se inválido, retorna erro 422 com detalhes
- O campo
-
Operações em lote (
POST /bulk):- Todos os documentos são validados
- Se qualquer um falhar, nenhum é salvo (transação atômica)
Exemplo de Erro de Validação
Requisição
curl -X POST "https://api.../production/context/orders/type/invoice/INV-001" \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"environment": "production",
"context": "orders",
"type": "invoice",
"key": "INV-001",
"data": {
"customer_id": "invalid-format",
"amount": -100,
"currency": "INVALID"
}
}'Resposta (422 Unprocessable Entity)
{
"message": "Schema validation failed",
"errors": [
{
"property": "customer_id",
"message": "Does not match the regex pattern ^CUST-[0-9]+$"
},
{
"property": "amount",
"message": "Must be greater than or equal to 0"
},
{
"property": "currency",
"message": "Does not have a value in the enumeration [\"BRL\",\"USD\",\"EUR\"]"
},
{
"property": "status",
"message": "The property status is required"
}
]
}Exemplos Práticos
Exemplo 1: Schema para Usuários
{
"schema": {
"type": "object",
"required": ["name", "email", "role"],
"properties": {
"name": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"role": {
"type": "string",
"enum": ["admin", "user", "guest"]
},
"age": {
"type": "integer",
"minimum": 18,
"maximum": 120
},
"phone": {
"type": "string",
"pattern": "^\\+?[1-9]\\d{1,14}$"
},
"address": {
"type": "object",
"properties": {
"street": {"type": "string"},
"city": {"type": "string"},
"state": {"type": "string"},
"zipcode": {"type": "string"}
}
}
}
}
}Exemplo 2: Schema para Produtos
{
"schema": {
"type": "object",
"required": ["sku", "name", "price", "stock"],
"properties": {
"sku": {
"type": "string",
"pattern": "^[A-Z]{3}-[0-9]{4}$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"description": {
"type": "string",
"maxLength": 1000
},
"price": {
"type": "number",
"minimum": 0,
"multipleOf": 0.01
},
"stock": {
"type": "integer",
"minimum": 0
},
"category": {
"type": "string",
"enum": ["electronics", "clothing", "food", "books"]
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"dimensions": {
"type": "object",
"required": ["width", "height", "depth"],
"properties": {
"width": {"type": "number", "minimum": 0},
"height": {"type": "number", "minimum": 0},
"depth": {"type": "number", "minimum": 0},
"unit": {"type": "string", "enum": ["cm", "m", "in"]}
}
}
}
}
}Exemplo 3: Schema para Logs
{
"schema": {
"type": "object",
"required": ["timestamp", "level", "message"],
"properties": {
"timestamp": {
"type": "string",
"format": "date-time"
},
"level": {
"type": "string",
"enum": ["debug", "info", "warning", "error", "critical"]
},
"message": {
"type": "string",
"minLength": 1
},
"context": {
"type": "object"
},
"user_id": {
"type": "string"
},
"ip": {
"type": "string",
"format": "ipv4"
},
"user_agent": {
"type": "string"
}
}
}
}Exemplo 4: Schema com Validações Condicionais
{
"schema": {
"type": "object",
"required": ["type", "value"],
"properties": {
"type": {
"type": "string",
"enum": ["personal", "business"]
},
"value": {
"type": "number",
"minimum": 0
},
"document": {
"type": "string"
}
},
"if": {
"properties": {
"type": {"const": "business"}
}
},
"then": {
"required": ["document"],
"properties": {
"document": {
"pattern": "^\\d{2}\\.\\d{3}\\.\\d{3}/\\d{4}-\\d{2}$"
}
}
}
}
}JSON Schema Reference
Tipos de Dados (type)
| Tipo | Descrição | Exemplo |
|---|---|---|
string | Texto | "Hello" |
number | Número (inteiro ou decimal) | 42, 3.14 |
integer | Número inteiro | 42 |
boolean | Booleano | true, false |
object | Objeto JSON | {"key": "value"} |
array | Array | [1, 2, 3] |
null | Nulo | null |
Validações para Strings
| Propriedade | Descrição | Exemplo |
|---|---|---|
minLength | Comprimento mínimo | {"minLength": 2} |
maxLength | Comprimento máximo | {"maxLength": 100} |
pattern | Regex | {"pattern": "^[A-Z]+$"} |
format | Formato predefinido | {"format": "email"} |
enum | Lista de valores | {"enum": ["A", "B"]} |
Formatos suportados:
date-time: ISO 8601 date-timedate: Data (YYYY-MM-DD)time: Hora (HH:MM:SS)email: Email válidoipv4: Endereço IPv4ipv6: Endereço IPv6uri: URI válidauuid: UUID válido
Validações para Numbers
| Propriedade | Descrição | Exemplo |
|---|---|---|
minimum | Valor mínimo | {"minimum": 0} |
maximum | Valor máximo | {"maximum": 100} |
exclusiveMinimum | Maior que (exclusivo) | {"exclusiveMinimum": 0} |
exclusiveMaximum | Menor que (exclusivo) | {"exclusiveMaximum": 100} |
multipleOf | Múltiplo de | {"multipleOf": 0.01} |
Validações para Arrays
| Propriedade | Descrição | Exemplo |
|---|---|---|
items | Schema dos itens | {"items": {"type": "string"}} |
minItems | Mínimo de itens | {"minItems": 1} |
maxItems | Máximo de itens | {"maxItems": 10} |
uniqueItems | Itens únicos | {"uniqueItems": true} |
Validações para Objects
| Propriedade | Descrição | Exemplo |
|---|---|---|
properties | Define propriedades | Ver exemplos acima |
required | Propriedades obrigatórias | {"required": ["name"]} |
minProperties | Mínimo de propriedades | {"minProperties": 1} |
maxProperties | Máximo de propriedades | {"maxProperties": 10} |
additionalProperties | Permite propriedades extras | {"additionalProperties": false} |
Combinadores
| Propriedade | Descrição |
|---|---|
allOf | Deve corresponder a todos os schemas |
anyOf | Deve corresponder a pelo menos um schema |
oneOf | Deve corresponder a exatamente um schema |
not | Não deve corresponder ao schema |
Casos de Uso Avançados
Caso 1: Diferentes Schemas por Ambiente
# Schema para production (mais restritivo)
curl -X POST "https://api.../production/context/orders/type/invoice/schema" \
-H "Authorization: Bearer {TOKEN}" \
-d '{
"schema": {
"type": "object",
"required": ["customer_id", "amount", "currency", "status", "payment_method"],
"properties": { ... }
}
}'
# Schema para development (mais flexível)
curl -X POST "https://api.../development/context/orders/type/invoice/schema" \
-H "Authorization: Bearer {TOKEN}" \
-d '{
"schema": {
"type": "object",
"required": ["customer_id", "amount"],
"properties": { ... }
}
}'Caso 2: Evolução de Schema
V1 do schema (inicial):
{
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"}
}
}
}V2 do schema (adicionar campo opcional):
{
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"},
"email": {"type": "string", "format": "email"}
}
}
}V3 do schema (tornar campo obrigatório):
{
"schema": {
"type": "object",
"required": ["name", "email"],
"properties": {
"name": {"type": "string"},
"email": {"type": "string", "format": "email"}
}
}
}Caso 3: Validação Personalizada com Regex
{
"schema": {
"type": "object",
"required": ["cpf", "phone", "postal_code"],
"properties": {
"cpf": {
"type": "string",
"pattern": "^\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}$",
"description": "CPF no formato XXX.XXX.XXX-XX"
},
"phone": {
"type": "string",
"pattern": "^\\([0-9]{2}\\) [0-9]{4,5}-[0-9]{4}$",
"description": "Telefone no formato (XX) XXXXX-XXXX"
},
"postal_code": {
"type": "string",
"pattern": "^\\d{5}-\\d{3}$",
"description": "CEP no formato XXXXX-XXX"
}
}
}
}Boas Práticas
1. Defina Campos Obrigatórios
// ✅ Bom: Campos críticos são obrigatórios
{
"type": "object",
"required": ["customer_id", "amount", "currency"],
"properties": { ... }
}
// ❌ Ruim: Tudo opcional
{
"type": "object",
"properties": { ... }
}2. Use Validações Apropriadas
// ✅ Bom: Validações específicas
{
"amount": {
"type": "number",
"minimum": 0,
"multipleOf": 0.01
},
"email": {
"type": "string",
"format": "email"
}
}
// ❌ Ruim: Sem validações
{
"amount": {"type": "number"},
"email": {"type": "string"}
}3. Documente com Descriptions
{
"properties": {
"status": {
"type": "string",
"enum": ["pending", "paid", "cancelled"],
"description": "Status do pagamento: pending (aguardando), paid (pago), cancelled (cancelado)"
}
}
}4. Use Enums para Valores Fixos
// ✅ Bom: Enum previne erros de digitação
{
"currency": {
"type": "string",
"enum": ["BRL", "USD", "EUR"]
}
}
// ❌ Ruim: Aceita qualquer string
{
"currency": {"type": "string"}
}5. Valide Formatos
{
"properties": {
"email": {"type": "string", "format": "email"},
"website": {"type": "string", "format": "uri"},
"created_at": {"type": "string", "format": "date-time"}
}
}6. Limite Tamanhos
{
"name": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"description": {
"type": "string",
"maxLength": 1000
},
"tags": {
"type": "array",
"maxItems": 10
}
}Troubleshooting
Erro 422 - Validation Failed
Sintomas:
{
"message": "Schema validation failed",
"errors": [...]
}Solução:
- Leia os erros retornados
- Corrija os dados conforme o schema
- Tente novamente
Schema Não Está Validando
Possíveis causas:
- Schema não foi criado para este escopo exato
- Schema foi deletado
- Erro no formato do schema JSON
Verificação:
# Verifique se o schema existe
curl -X GET "https://api.../schema" \
-H "Authorization: Bearer {TOKEN}"Como Testar um Schema
# 1. Crie um schema de teste
curl -X POST "https://api.../testing/context/test/type/sample/schema" \
-H "Authorization: Bearer {TOKEN}" \
-d '{"schema": {...}}'
# 2. Tente criar um documento válido
curl -X POST "https://api.../testing/context/test/type/sample/doc-001" \
-H "Authorization: Bearer {TOKEN}" \
-d '{
"environment": "testing",
"context": "test",
"type": "sample",
"key": "doc-001",
"data": { /* dados válidos */ }
}'
# 3. Tente criar um documento inválido (deve falhar)
curl -X POST "https://api.../testing/context/test/type/sample/doc-002" \
-H "Authorization: Bearer {TOKEN}" \
-d '{
"environment": "testing",
"context": "test",
"type": "sample",
"key": "doc-002",
"data": { /* dados inválidos */ }
}'Recursos Externos
JSON Schema
- Especificação Oficial: json-schema.org
- Understanding JSON Schema: json-schema.org/understanding-json-schema
- JSON Schema Validator: jsonschemavalidator.net
Ferramentas Online
- JSON Schema Generator: Gere schemas a partir de exemplos JSON
- JSON Schema Validator: Valide seus schemas online
Updated 6 days ago
