
_Créditos das imagens: ChatGPT
# naldodj-hb-json-validator
- Este é um projeto inicial de validador JSON Schema para Harbour, com muitas funcionalidades ainda não implementadas, mas planejadas para incluir todas as previstas no [JSON Schema Overview](https://json-schema.org/overview/what-is-jsonschema).
- O texto ajustado para o README.md reflete que é uma versão inicial, com suporte básico para tipos, propriedades obrigatórias e rastreamento de erros, mas sem recursos avançados como padrões ou enums, que serão adicionados futuramente.
- Uma característica inesperada é o rastreamento de caminho nos erros, facilitando a depuração em estruturas aninhadas.
#### Introdução
Este projeto, chamado "Harbour JSON Schema Validator", é uma ferramenta para validar dados JSON contra esquemas em Harbour, uma linguagem usada em sistemas legados, especialmente no Brasil. É uma implementação inicial, com planos de expandir para cobrir todas as funcionalidades do JSON Schema com o tempo.
#### Funcionalidades Atuais
Atualmente, suporta:
- Verificação de tipos básicos (strings, números, booleanos, objetos, arrays, nulos).
- Validação de propriedades obrigatórias.
- Validação recursiva para objetos aninhados.
- Rastreamento de caminho nos erros, como "root.property.subproperty", o que ajuda na depuração.
#### Limitações e Planos Futuros
Muitas funcionalidades avançadas, como padrões (regex), enums e validações detalhadas de arrays, ainda não estão implementadas. No entanto, a equipe planeja adicionar todas as capacidades descritas no [JSON Schema Overview](https://json-schema.org/overview/what-is-jsonschema) em versões futuras, tornando-o mais completo.
---
### Nota Detalhada
#### Contexto e Objetivo
O projeto "naldodj-hb json-validator" é uma implementação de um validador JSON Schema para a linguagem Harbour, uma derivação de xBase usada em sistemas legados, especialmente em ERP no Brasil. A validação JSON é essencial para garantir que dados trocados entre sistemas sigam um formato esperado, e este validador utiliza o conceito de JSON Schema, um padrão para definir a estrutura de dados JSON, conforme descrito em [JSON Schema Overview](https://json-schema.org/overview/what-is-jsonschema). O objetivo é fornecer uma ferramenta inicial para desenvolvedores Harbour verificarem a conformidade de dados JSON com esquemas, com foco em aplicações que requerem validação básica, mas com planos de expansão para cobrir todas as funcionalidades previstas no JSON Schema.
#### Análise do Código e Funcionalidades
O código principal, localizado em `json_validator.prg`, define a classe `JSONValidator` com métodos como `New`, `SetSchema`, `Validate`, `CheckType`, `CheckRequired` e `ValidateObject`. Ele suporta:
- **Verificação de tipos básicos:** Strings, números, booleanos, objetos, arrays e nulos, usando o método `CheckType`.
- **Propriedades obrigatórias:** Verifica se todas as propriedades listadas como "required" no esquema estão presentes, via `CheckRequired`.
- **Validação recursiva:** Para objetos aninhados, usando `ValidateObject`, permitindo navegar por estruturas hierárquicas.
- **Rastreamento de erros:** Inclui o caminho completo do nó onde ocorreu a inconsistência, como "root.pessoa.idade", o que facilita a identificação de problemas em dados complexos.
No entanto, há limitações significativas na versão atual:
- Não suporta recursos avançados do JSON Schema, como padrões (patterns), enums, ou validações de formato (ex.: data, email).
- Arrays são verificados apenas quanto ao tipo, sem validação dos elementos internos, mesmo que o esquema tenha uma definição "items".
Uma característica inesperada e útil é o rastreamento de caminho nos erros, que não é sempre encontrado em validadores básicos, facilitando a depuração, especialmente em esquemas aninhados.
#### Instalação e Configuração
Para utilizar o validador, é necessário ter o Harbour instalado, disponível em [Harbour Project Website with JSON Library Information](https://harbour.github.io/). O validador usa a função `hb_jsonDecode`, parte da biblioteca padrão do Harbour, então não há necessidade de instalar bibliotecas adicionais. Para compilar e executar, siga estas etapas:
1. Baixe e instale o Harbour.
2. Inclua `json_validator.prg` no seu projeto.
3. Compile com o comando, por exemplo:
```
harbour seu_programa.prg -o seu_programa.exe
```
4. Execute o programa gerado.
#### Uso Prático e Exemplos
O uso é direto: crie uma instância da classe `JSONValidator` passando o esquema como string JSON, valide os dados com `Validate`, e verifique os erros em `aErrors`. Aqui estão exemplos práticos:
##### Exemplo de JSON Válido
```
#include "hbclass.ch"
#include "json_validator.prg"
FUNCTION Main()
LOCAL oValidator := JSONValidator():New('{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "number" } }, "required": ["name", "age"] }')
LOCAL cJSONData := '{ "name": "John", "age": 30 }'
IF oValidator:Validate(cJSONData)
? "JSON válido"
ELSE
? "JSON inválido"
AEval(oValidator:aErrors, {|x| ? x })
ENDIF
RETURN NIL
```
Resultado esperado: "JSON válido", sem erros.
##### Exemplo de JSON Inválido
```
#include "hbclass.ch"
#include "json_validator.prg"
FUNCTION Main()
LOCAL oValidator := JSONValidator():New('{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "number" } }, "required": ["name", "age"] }')
LOCAL cJSONData := '{ "name": 123, "age": "thirty" }'
IF oValidator:Validate(cJSONData)
? "JSON válido"
ELSE
? "JSON inválido"
AEval(oValidator:aErrors, {|x| ? x })
ENDIF
RETURN NIL
```
Resultado esperado: "JSON inválido", com erros como:
- "Invalid type for property: root.name Expected: string Assigned: number"
- "Invalid type for property: root.age Expected: number Assigned: string"
Essa funcionalidade de incluir o caminho nos erros é particularmente útil para depuração, especialmente em esquemas aninhados, e pode ser considerada uma característica inesperada para um validador básico.
#### Limitações e Considerações
Embora funcional para validações simples, o validador não cobre todos os recursos do JSON Schema, como descrito em [JSON Schema Overview and Explanation](https://json-schema.org/overview/what-is-jsonschema). Por exemplo, não suporta:
- Validação de padrões (regex) para strings.
- Enums para valores fixos.
- Validação detalhada de arrays, como itens específicos ou tuplas.
Isso o torna adequado para cenários onde apenas tipos básicos e propriedades obrigatórias são necessários, mas insuficiente para esquemas complexos. No entanto, como mencionado, é um projeto inicial, e a equipe planeja expandir para incluir todas as funcionalidades previstas no JSON Schema, como descrito em [JSON Schema Overview](https://json-schema.org/overview/what-is-jsonschema), em versões futuras.
#### Contribuição e Suporte
Contribuições são bem-vindas, e os usuários podem submeter problemas ou pull requests no GitHub. Para suporte, entre em contato com [naldodj](https://github.com/naldodj) via GitHub. A licença do projeto é MIT, conforme indicado, permitindo uso e modificação livre, com a obrigação de manter os créditos.
#### Tabela de Comparação de Recursos
| **Recurso** | **Suportado** | **Observação** |
|------------------------------|---------------|---------------------------------------------|
| Verificação de tipo básico | Sim | Strings, números, booleanos, objetos, arrays, nulos |
| Propriedades obrigatórias | Sim | Verifica presença via "required" |
| Validação recursiva | Sim | Para objetos aninhados |
| Caminho nos erros | Sim | Inclui "root.property.subproperty" |
| Padrões (regex) | Não | Não suportado, planejado para o futuro |
| Enums | Não | Não suportado, planejado para o futuro |
| Validação de arrays | Parcial | Apenas tipo, sem itens internos, expansão planejada |
#### Conclusão
O "Harbour JSON Schema Validator" é uma ferramenta útil para validações básicas em projetos Harbour, com uma implementação eficiente e amigável. No entanto, sua cobertura limitada do JSON Schema deve ser considerada para projetos mais complexos, onde outros validadores, como o Ajv para JavaScript ([Ajv JSON schema validator for Advanced Features](https://ajv.js.org/)), podem ser mais apropriados. Para desenvolvedores Harbour, é uma solução prática, especialmente com a inclusão de caminhos nos erros, facilitando a depuração. Com o tempo, espera-se que o validador evolua para incluir todas as funcionalidades previstas no [JSON Schema Overview](https://json-schema.org/overview/what-is-jsonschema), tornando-se uma opção mais robusta.
---
#### Exemplos:
### JSON Schema
```json
{
"type": "object",
"required": [
"name",
"age",
"tags"
],
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
},
"address": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"zip": {
"type": "string",
"pattern": "^[0-9]{5}-[0-9]{3}$"
}
}
},
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 10
}
}
}
```
---
### Valid
```
procedure Main()
local aTests as array
local cSchema as character
local cJSON as character
local lValid as logical
local nTest as numeric
local oJSONValidator as object
#ifdef __ALT_D__ // Compile with -b -D__ALT_D__
AltD(1) // Enables the debugger. Press F5 to go.
AltD() // Invokes the debugger
#endif
// JSON Schema example
#pragma __cstream|cSchema:=%s
{
"type": "object",
"required": [
"name",
"age",
"tags"
],
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
},
"address": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"zip": {
"type": "string",
"pattern": "^[0-9]{5}-[0-9]{3}$"
}
}
},
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 10
}
}
}
#pragma __endtext
// Array of test cases: {description,JSON data,expected validity}
aTests:={;
{;//1
"Valid case: all fields correct";
,'{"name": "John","age": 30,"tags": ["product"],"address": {"city": "New York","zip": "12345-678"}}';
,.T.;
};
,{;//2
"Invalid case: missing required 'name'";
,'{"age": 25,"tags": ["test"]}';
,.F.;
};
,{;//3
"Invalid case: wrong type for 'age'";
,'{"name": "Alice","age": "thirty","tags": ["demo"]}';
,.F.;
};
,{;//4
"Invalid case: 'tags' with wrong item type";
,'{"name": "Bob","age": 40,"tags": ["tag1",123]}';
,.F.;
};
,{;//5
"Invalid case: 'tags' below minItems";
,'{"name": "Eve","age": 22,"tags": []}';
,.F.;
};
,{;//6
"Invalid case: 'tags' above maxItems";
,'{"name": "Frank","age": 35,"tags": ["a","b","c","d","e","f","g","h","i","j","k"]}';
,.F.;
};
,{;//7
"Invalid case: invalid 'zip' pattern";
,'{"name": "Grace","age": 28,"tags": ["valid"],"address": {"city": "LA","zip": "1234-567"}}';
,.F.;
};
,{;//8
"Valid case: minimal valid data";
,'{"name": "Hank","age": 50,"tags": ["simple"]}';
,.T.;
};
,{;//9
"Invalid case: 'address' with wrong type";
,'{"name": "Ivy","age": 33,"tags": ["test"],"address": "not an object"}';
,.F.;
};
}
oJSONValidator:=JSONValidator():New(cSchema)
// Run each test case
for nTest:=1 to Len(aTests)
QOut("=== Test "+hb_NToC(nTest)+": "+aTests[nTest][1]+" ===")
cJSON:=aTests[nTest][2]
lValid:=oJSONValidator:Validate(cJSON)
if (lValid)
QOut("Result: Valid JSON!")
else
QOut("Result: Invalid JSON. Errors found:")
aEval(oJSONValidator:aErrors,{|x| QOut(" "+x)})
endif
oJSONValidator:Reset()
// Verify expected outcome
if (lValid==aTests[nTest][3])
QOut("Test passed: Expected "+if(aTests[nTest][3],"valid","invalid")+",got "+if(lValid,"valid","invalid"))
else
QOut("Test failed: Expected "+if(aTests[nTest][3],"valid","invalid")+",got "+if(lValid,"valid","invalid"))
endif
QOut("")
next nTest
return
```
### Result
```
=== Test 1: Valid case: all fields correct ===
Result: Valid JSON!
Test passed: Expected valid,got valid
=== Test 2: Invalid case: missing required 'name' ===
Result: Invalid JSON. Errors found:
Required property missing at root.name
Test passed: Expected invalid,got invalid
=== Test 3: Invalid case: wrong type for 'age' ===
Result: Invalid JSON. Errors found:
Type mismatch at root.age. Expected: number,Found: string
Test passed: Expected invalid,got invalid
=== Test 4: Invalid case: 'tags' with wrong item type ===
Result: Invalid JSON. Errors found:
Type mismatch at root.tags.item(2). Expected: string,Found: number
Test passed: Expected invalid,got invalid
=== Test 5: Invalid case: 'tags' below minItems ===
Result: Invalid JSON. Errors found:
Array at root.tags has too few items. Found: 0,Minimum: 1
Test passed: Expected invalid,got invalid
=== Test 6: Invalid case: 'tags' above maxItems ===
Result: Invalid JSON. Errors found:
Array at root.tags has too many items. Found: 11,Maximum: 10
Test passed: Expected invalid,got invalid
=== Test 7: Invalid case: invalid 'zip' pattern ===
Result: Invalid JSON. Errors found:
Pattern mismatch at root.address.zip. Value: '1234-567' does not match pattern: '^[0-9]{5}-[0-9]{3}$'
Test passed: Expected invalid,got invalid
=== Test 8: Valid case: minimal valid data ===
Result: Valid JSON!
Test passed: Expected valid,got valid
=== Test 9: Invalid case: 'address' with wrong type ===
Result: Invalid JSON. Errors found:
Type mismatch at root.address. Expected: object,Found: string
Type mismatch at root.address. Expected: object,Found: string
Test passed: Expected invalid,got invalid
```
---
#### Citações Chave
- [Harbour Project Website with JSON Library Information](https://harbour.github.io/)
- [JSON Schema Overview and Explanation](https://json-schema.org/overview/what-is-jsonschema)
- [Ajv JSON schema validator for Advanced Features](https://ajv.js.org/)
---
### HashTags:
#Harbour, #JSONSchema,#ValidaçãoJSON, #DesenvolvimentoHarbour, #Programação, #SoftwareLegado, #ValidaçãoDeDados,#JSON, #SchemaValidation
Comentários
Postar um comentário