Validación JSON Schema: Datos, Documentación y Sugerencias

JSON Schema: El contrato de los datos

JSON Schema es el lenguaje de definición de estructuras para datos JSON — similar a TypeScript para JavaScript, pero aplicable a validación en tiempo de ejecución y escenarios multilenguaje.

Uso Descripción
Validación de datos Validación de solicitudes/respuestas de API
Generación de documentación Generación automática de documentación de API
Sugerencias del IDE Autocompletado inteligente en VS Code
Datos Mock Generación automática de datos de prueba
Validación de configuración package.json, tsconfig.json, etc.

I. Tipos básicos

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 1, "maxLength": 100 },
    "age": { "type": "integer", "minimum": 0, "maximum": 150 },
    "email": { "type": "string", "format": "email" },
    "isActive": { "type": "boolean" },
    "score": { "type": "number", "minimum": 0, "maximum": 100 },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1,
      "maxItems": 10,
      "uniqueItems": true
    }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}

Formatos integrados

format Regla de coincidencia Ejemplo
email RFC 5322 user@example.com
uri URI https://example.com
date Fecha ISO 8601 2026-06-02
time Hora ISO 8601 14:30:00
date-time Fecha y hora ISO 8601 2026-06-02T14:30:00Z
ipv4 Dirección IPv4 192.168.1.1
ipv6 Dirección IPv6 ::1
uuid UUID 550e8400-e29b-41d4-a716-446655440000
hostname Nombre de host example.com

II. Patrones avanzados

Objetos anidados

{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "profile": {
          "type": "object",
          "properties": {
            "avatar": { "type": "string", "format": "uri" },
            "bio": { "type": "string", "maxLength": 200 }
          }
        }
      }
    }
  }
}

Enumeraciones y tipos de unión

{
  "status": {
    "type": "string",
    "enum": ["pending", "active", "completed", "cancelled"]
  },
  "id": {
    "oneOf": [
      { "type": "string", "format": "uuid" },
      { "type": "integer", "minimum": 1 }
    ]
  }
}

Validación condicional

{
  "type": "object",
  "properties": {
    "paymentMethod": { "type": "string", "enum": ["credit_card", "bank_transfer"] },
    "cardNumber": { "type": "string" },
    "bankAccount": { "type": "string" }
  },
  "if": {
    "properties": { "paymentMethod": { "const": "credit_card" } }
  },
  "then": {
    "required": ["cardNumber"],
    "properties": { "cardNumber": { "pattern": "^\\d{16}$" } }
  },
  "else": {
    "required": ["bankAccount"]
  }
}

Patrones de expresiones regulares

{
  "phone": { "type": "string", "pattern": "^1[3-9]\\d{9}$" },
  "postalCode": { "type": "string", "pattern": "^\\d{6}$" },
  "slug": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
}

III. $ref y reutilización de definiciones

{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zipCode": { "type": "string", "pattern": "^\\d{6}$" }
      },
      "required": ["street", "city", "zipCode"]
    }
  },
  "type": "object",
  "properties": {
    "homeAddress": { "$ref": "#/$defs/address" },
    "workAddress": { "$ref": "#/$defs/address" }
  }
}

IV. Validación en tiempo de ejecución

Ajv (el validador más rápido)

import Ajv from 'ajv';

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

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

const validate = ajv.compile(schema);

const valid = validate({ name: '张三', age: 25 });
if (!valid) {
  console.log(validate.errors);
  // [{ keyword: 'minimum', dataPath: '/age', message: 'must be >= 0' }]
}

Zod (TypeScript primero)

import { z } from 'zod';

const UserSchema = z.object({
  name: z.string().min(1).max(100),
  age: z.number().int().min(0).max(150),
  email: z.string().email(),
  tags: z.array(z.string()).min(1).max(10),
});

// Inferencia automática de tipos
type User = z.infer<typeof UserSchema>;

// Validación
const result = UserSchema.safeParse(input);
if (result.success) {
  console.log(result.data); // Tipo seguro
} else {
  console.log(result.error.issues);
}

V. Sugerencias inteligentes del IDE

Configuración de VS Code

// .vscode/settings.json
{
  "json.schemas": [
    {
      "fileMatch": ["/config/*.json"],
      "url": "./schemas/config-schema.json"
    },
    {
      "fileMatch": ["package.json"],
      "url": "https://json.schemastore.org/package"
    }
  ]
}

Referenciar Schema en archivos JSON

{
  "$schema": "./schemas/config-schema.json",
  "name": "my-project"
  // Autocompletado del IDE, indicaciones de errores
}

Schema Store

Schema Store proporciona más de 400 JSON Schema comunes:

  • package.json
  • tsconfig.json
  • .eslintrc.json
  • docker-compose.json
  • GitHub Actions workflows

VI. Generar Schema a partir de JSON

Uso de herramientas

  1. Abre la Herramienta de formateo JSON
  2. Pega los datos JSON
  3. Haz clic en "Generar Schema"
  4. Inferencia automática de tipos, enumeraciones y rangos

Herramientas de línea de comandos

# Usar json-schema-generator
npx json-schema-generator sample.json -o schema.json

# Usar quicktype
npx quicktype sample.json -o schema.json --lang schema

VII. Generación de datos Mock

import { faker } from '@faker-js/faker';

// Generar datos Mock basados en Schema
function generateMock(schema) {
  if (schema.type === 'string') {
    if (schema.format === 'email') return faker.internet.email();
    if (schema.format === 'uri') return faker.internet.url();
    if (schema.enum) return faker.helpers.arrayElement(schema.enum);
    return faker.lorem.word();
  }
  if (schema.type === 'integer') return faker.number.int(schema);
  if (schema.type === 'boolean') return faker.datatype.boolean();
  if (schema.type === 'array') {
    return Array.from({ length: 3 }, () => generateMock(schema.items));
  }
  if (schema.type === 'object') {
    const result = {};
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      result[key] = generateMock(propSchema);
    }
    return result;
  }
}

VIII. Mejores prácticas

  1. Siempre declarar $schema: Especificar la versión Draft para evitar ambigüedades
  2. Usar additionalProperties: false: Prohibir campos no definidos
  3. Usar $defs + $ref: Reutilizar estructuras comunes
  4. Usar format en lugar de escribir pattern manualmente: Más legible, el validador lo maneja automáticamente
  5. Integrar validación en CI: Asegurar que las respuestas de API siempre cumplan con el Schema
  6. Gestionar versiones del Schema: Sincronizar con las versiones de la API, soportar verificación de compatibilidad hacia atrás
#JSON Schema#数据校验#Ajv#Zod#API