Skip to content
SP StackPractices
intermediate Por StackPractices

Validar JSON Schema

Cómo validar datos JSON contra schemas en Python, Java y JavaScript.

Temas: data

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Visión General

JSON Schema define la estructura, tipos y restricciones de datos JSON. Es el estándar de la industria para validar cuerpos de solicitudes de API, archivos de configuración y mensajes entre servicios. Implementar validación de schemas desde el inicio captura datos malformados antes de que lleguen a la lógica de negocio, reduciendo bugs y riesgos de seguridad.

Cuándo Usar

Usa este recurso cuando:

  • Valides payloads de solicitudes de API REST antes de procesarlos
  • Impongas contratos entre microservicios vía schemas de mensajes
  • Valides archivos de configuración generados por usuarios al iniciar
  • Generes tipos TypeScript, documentación o especificaciones OpenAPI desde schemas

Solución

Python

# jsonschema es la librería más popular en Python
# pip install jsonschema
from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string", "minLength": 1},
        "age": {"type": "integer", "minimum": 0},
        "email": {"type": "string", "format": "email"}
    },
    "required": ["name", "age", "email"]
}

try:
    validate(instance={"name": "Ada", "age": 30, "email": "ada@example.com"}, schema=schema)
    print("Válido")
except ValidationError as e:
    print(f"Inválido: {e.message}")

JavaScript

// Ajv es el validador JSON Schema más rápido para JavaScript
// npm install ajv
import Ajv from 'ajv';

const ajv = new Ajv({ allErrors: true });

const schema = {
    type: 'object',
    properties: {
        name: { type: 'string', minLength: 1 },
        age: { type: 'integer', minimum: 0 },
        email: { type: 'string', format: 'email' }
    },
    required: ['name', 'age', 'email']
};

const validate = ajv.compile(schema);
const valid = validate({ name: 'Ada', age: 30, email: 'ada@example.com' });

if (!valid) {
    console.log(validate.errors);
}

Java

// networknt/json-schema-validator es una opción popular y ligera
// Maven: com.networknt:json-schema-validator
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.ValidationMessage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
JsonSchema schema = factory.getSchema("{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"}},\"required\":[\"name\"]}");

ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree("{\"name\":\"Ada\"}");
Set<ValidationMessage> errors = schema.validate(node);

if (!errors.isEmpty()) {
    errors.forEach(System.out::println);
}

Explicación

JSON Schema es especificado por la JSON Schema Organization y soporta los drafts 04, 06, 07, 2019-09 y 2020-12. Las palabras clave de validación principales incluyen type, properties, required, minimum/maximum, pattern, enum y format. Las características avanzadas incluyen $ref para composición, if/then/else para schemas condicionales y unevaluatedProperties para validación estricta.

La mayoría de los validadores también soportan formatos personalizados (email, uri, date-time) y vocabularios definidos por el usuario. Ajv además soporta compilación inline a funciones JavaScript para máximo rendimiento.

Variantes

TecnologíaLibreríaSoporte de DraftNotas
Pythonjsonschema04, 06, 07, 2019, 2020Más features, algo más lento
Pythonfastjsonschema07, 2020Compila a código Python, muy rápido
JavaScriptAjv04, 06, 07, 2019, 2020Validador JS más rápido, compila schemas
JavaScriptzodN/A (similar)Schemas type-first, no requiere JSON Schema
Javanetworknt04, 06, 07, 2019, 2020Ligero, integración con Jackson
Javaeverit04, 06, 07Maduro, cumplimiento estricto

Mejores Prácticas

  • Usa modo estricto (additionalProperties: false) para rechazar campos inesperados y detectar errores tipográficos
  • Retorna todos los errores a la vez (allErrors: true en Ajv) para mejor UX en formularios
  • Versiona tus schemas junto con las versiones de API para evitar cambios breaking
  • Reutiliza definiciones con $ref en lugar de duplicar sub-schemas comunes
  • Mantén schemas en archivos .json bajo control de versiones, no inline en código

Errores Comunes

  • Usar type: "number" para enteros: Usa type: "integer" cuando se requieren números enteros
  • Olvidar arrays required: Las propiedades son opcionales por defecto; lista explícitamente las requeridas
  • Validar archivos grandes sincrónicamente: La validación de schemas puede bloquear el event loop; usa streams o worker threads
  • No fijar la versión del draft: Diferentes validadores usan drafts por defecto distintos; siempre especifica $schema
  • Ignorar validación de formatos: Formatos como email y date-time pueden omitirse por defecto; habilítalos explícitamente

Preguntas Frecuentes

¿Qué draft de JSON Schema debo usar?

El Draft 2020-12 es la última versión estable y está soportada por Ajv, jsonschema y networknt. Úsalo para proyectos nuevos. Solo usa drafts antiguos al integrar con sistemas legacy.

¿Puedo generar tipos TypeScript desde JSON Schema?

Sí. Herramientas como json-schema-to-typescript (npm) y QuickType generan interfaces TypeScript desde schemas. A la inversa, Zod y TypeBox te permiten definir schemas como tipos TypeScript primero.

¿Cómo valido objetos profundamente anidados eficientemente?

Usa $ref para modularizar sub-schemas y habilita compilación (Ajv compile(), fastjsonschema). En Python, fastjsonschema compila schemas a código Python, ofreciendo 100x+ de aceleración sobre validación interpretada.