Schema

Estándares Security Notes Jan 9, 2026 JSON
schema json-schema validation data-modeling api-design

Definición

Un schema es un plano que define cómo se ven los datos - su estructura, tipos, campos obligatorios, reglas de validación y restricciones. En contextos de API, los schemas se escriben típicamente en JSON Schema, un vocabulario que te permite anotar y validar documentos JSON. Piensa en un schema como un contrato: le dice a los clientes de la API exactamente qué forma deben tener los datos para que las peticiones tengan éxito, y qué forma esperar en las respuestas.

Los schemas son tanto documentación legible por humanos como lógica de validación ejecutable por máquinas. Un desarrollador puede leer un schema para entender que un objeto “usuario” requiere un campo email (string, formato email) y un campo age (integer, 18-120). Las herramientas pueden validar automáticamente datos entrantes contra ese mismo schema, rechazando peticiones inválidas antes de que lleguen a la lógica de negocio.

En OpenAPI, los schemas definen cuerpos de petición, cuerpos de respuesta, parámetros y modelos de datos reutilizables. En bases de datos, los schemas definen estructuras de tablas. En GraphQL, los schemas definen queries y mutations. Donde sea que encuentres datos estructurados, encontrarás schemas describiéndolos.

Ejemplo

Schema de Producto E-commerce: La API de una tienda online define un schema de Producto que requiere campos como SKU (string, pattern: ^[A-Z0-9-]+$), price (number, minimum: 0.01), stock (integer, minimum: 0), y campos opcionales como description. Este schema valida productos de proveedores antes de importarlos al catálogo.

Schema de Registro de Usuario: Una red social define un schema para registro de usuarios que requiere email (format: email), password (minLength: 12, pattern: debe incluir mayúscula, minúscula, número, símbolo), username (pattern: alfanumérico, 3-20 chars), y campos opcionales como bio (maxLength: 500). Los registros inválidos se rechazan antes de escrituras en base de datos.

Schema de Procesamiento de Pagos: Los schemas de la API de Stripe validan datos de tarjetas de crédito - cardNumber (string, pattern: 13-19 dígitos), expiryDate (pattern: MM/YY), CVV (pattern: 3-4 dígitos). El schema usa validación condicional: si paymentMethod es “card”, estos campos son obligatorios; si “bank_transfer”, aplican campos diferentes.

Schema de Datos de Sensor IoT: Una plataforma de hogar inteligente define schemas para lecturas de sensores. Los sensores de temperatura deben enviar lecturas como floats entre -50.0 y 150.0 con un timestamp (formato ISO 8601) y sensorId (UUID). Las lecturas inválidas se marcan antes del almacenamiento.

Schema de Archivo de Configuración: Los archivos Docker Compose se validan contra un JSON Schema. El schema requiere version (string), services (objeto con propiedades específicas), y opcionalmente networks, volumes. Los IDEs usan este schema para proporcionar autocompletado y validación mientras editas archivos docker-compose.yml.

Analogía

El Código de Construcción: Así como los códigos de construcción especifican que el cableado eléctrico debe ser de cobre calibre 14, correr a través de conductos y terminar en enchufes debidamente conectados a tierra, un schema especifica que un campo “address” debe ser un string, máximo 200 caracteres, y coincidir con un patrón que parezca una dirección real. Los inspectores (validadores) revisan edificios contra el código así como los API gateways revisan peticiones contra schemas.

La Tarjeta de Receta: Un schema de receta define ingredients (array de objetos con name, quantity, unit), instructions (array de strings), prepTime (integer, minutos), servings (integer, positivo). Así como no puedes hornear un pastel sin harina (campo obligatorio), no puedes enviar una receta sin ingredientes. El schema asegura que cada receta sigue la misma estructura.

El Formulario de Solicitud de Empleo: Un schema es como un formulario de solicitud de empleo estandarizado - especifica qué campos son obligatorios (nombre, email), cuáles son opcionales (carta de presentación), qué formatos son aceptables (número de teléfono debe ser 10 dígitos), y qué valores son válidos (año de graduación debe estar entre 1950 y año actual). Las solicitudes que no siguen el formulario se rechazan inmediatamente.

Ejemplo de Código


{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/user.json",
  "title": "User",
  "description": "A registered user in the system",
  "type": "object",
  "required": ["id", "email", "username"],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Unique identifier for the user"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "User's email address"
    },
    "username": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9_]{3,20}$",
      "description": "Username (3-20 alphanumeric characters or underscores)"
    },
    "age": {
      "type": "integer",
      "minimum": 18,
      "maximum": 120,
      "description": "User's age"
    },
    "role": {
      "type": "string",
      "enum": ["admin", "moderator", "user"],
      "default": "user"
    },
    "preferences": {
      "type": "object",
      "properties": {
        "newsletter": {
          "type": "boolean",
          "default": false
        },
        "theme": {
          "type": "string",
          "enum": ["light", "dark", "auto"],
          "default": "auto"
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time",
      "description": "Account creation timestamp"
    }
  },
  "additionalProperties": false
}

Validando datos contra schema (JavaScript):


const Ajv = require("ajv");
const addFormats = require("ajv-formats");

const ajv = new Ajv();
addFormats(ajv);

const schema = {
  type: "object",
  required: ["email", "username"],
  properties: {
    email: { type: "string", format: "email" },
    username: {
      type: "string",
      pattern: "^[a-zA-Z0-9_]{3,20}$"
    },
    age: {
      type: "integer",
      minimum: 18,
      maximum: 120
    }
  }
};

const validate = ajv.compile(schema);

// Datos válidos
const validUser = {
  email: "[email protected]",
  username: "alice_123",
  age: 25
};
console.log(validate(validUser)); // true

// Datos inválidos
const invalidUser = {
  email: "not-an-email",
  username: "ab", // muy corto
  age: 15 // muy joven
};
console.log(validate(invalidUser)); // false
console.log(validate.errors);
// [
//   { instancePath: '/email', message: 'must match format "email"' },
//   { instancePath: '/username', message: 'must match pattern ...' },
//   { instancePath: '/age', message: 'must be >= 18' }
// ]

Diagrama

graph TB
    subgraph "Flujo de Validación de Schema"
        CLIENT[Cliente] -->|Envía Datos| GATE[API Gateway]
        GATE -->|Valida| SCHEMA[JSON Schema]

        SCHEMA -->|Válido| HANDLER[Request Handler]
        SCHEMA -->|Inválido| ERROR[400 Bad Request
Errores de Validación] HANDLER -->|Response| SCHEMA2[Response Schema] SCHEMA2 -->|Valida| RESP[Enviar Respuesta] SCHEMA2 -->|Inválido| LOG[Log Schema Violation
Alertar Desarrolladores] end subgraph "Definición de Schema" DEF[Archivo Schema] DEF --> TYPES[Definiciones de Tipo
string, number, object] DEF --> RULES[Reglas de Validación
min, max, pattern] DEF --> REQ[Campos Obligatorios] DEF --> FORMAT[Formatos
email, uuid, date-time] end SCHEMA -.Referencias.- DEF SCHEMA2 -.Referencias.- DEF style SCHEMA fill:#90EE90 style ERROR fill:#FF6B6B style HANDLER fill:#87CEEB

Notas de Seguridad

SECURITY NOTES

CRÍTICO - …

Configuración y Validación:

  • Siempre valida entrada no confiable contra schemas antes de procesar.
  • Establece additionalProperties en false para prevenir inyección de campos inesperados.
  • Usa maxLength en strings para prevenir denegación de servicio vía cargas masivas.

Monitoreo y Protección:

  • Valida profundidad anidada para prevenir bombas recursivas.
  • Nunca confíes en schemas proporcionados por clientes.
  • Usa restricciones de pattern en campos que alimentan comandos de sistema o consultas SQL.
  • Sanitiza mensajes de error para evitar filtrar detalles del schema a atacantes.

Mejores Prácticas

  1. Fallar rápido con validación - Valida en el API gateway antes de que se ejecute lógica de negocio costosa
  2. Usar validación estricta - Establece additionalProperties: false para rechazar campos inesperados
  3. Proporcionar mensajes de error claros - Mapea errores de validación a mensajes legibles para desarrolladores
  4. Versionar tus schemas - Los schemas evolucionan; versiόnalos como APIs (cambios breaking vs. no-breaking)
  5. Reutilizar definiciones de schema - Usa $ref para referenciar schemas comunes, evitando duplicación
  6. Documentar con descripciones - Agrega campos description a cada propiedad para docs auto-generadas
  7. Testear casos extremos - Valida valores límite (min, max), arrays vacíos, manejo de null
  8. Usar validadores de formato - Aprovecha formatos incorporados (email, uuid, date-time) en lugar de patterns personalizados

Errores Comunes

Sobre-validación: Hacer cada campo obligatorio con patterns estrictos cuando se necesita flexibilidad. Empieza permisivo, endurece basado en problemas reales de datos.

Sub-validación: Aceptar cualquier string cuando necesitas emails, o cualquier número cuando necesitas enteros positivos. Esto empuja validación a la lógica de negocio donde es más difícil de mantener.

Permitir propiedades adicionales: Dejar additionalProperties: true (el default) permite a clientes enviar campos basura que pueden causar problemas de seguridad o romper actualizaciones futuras.

Mensajes de error vagos: Retornar “validation failed” en lugar de errores específicos a nivel de campo. Los desarrolladores necesitan saber exactamente qué está mal.

No validar respuestas: Solo validar peticiones entrantes pero ignorar schemas de respuesta. La validación de respuestas detecta bugs de backend temprano.

Regex catastrophic backtracking: Usar patterns regex complejos que causan complejidad temporal exponencial en ciertas entradas (ataques ReDoS).

Mezclar capas de validación: Validar los mismos datos en schema, lógica de negocio y restricciones de base de datos con reglas diferentes. Escoge una fuente de verdad.

Estándares y RFCs

Standards & RFCs
1)- JSON Schema Draft 2020-12
2)- JSON Schema Validation
3)- JSON Schema Core
4)- [OpenAPI 3](https://reference.apios.info/es/terms/openapi-3/).1.0 (usa JSON Schema)

Términos Relacionados