Referencia al Schema con el $id especificado.
Cada aplicación que recibe datos de fuentes externas enfrenta la misma pregunta fundamental: ¿puedo confiar en estos datos? Ya sean cuerpos de solicitud API, archivos de configuración, mensajes de cola o importaciones de datos, los datos no confiables deben validarse antes de ingresar a tu sistema. JSON Schema proporciona una forma estandarizada e independiente del lenguaje para definir cómo se ven los datos válidos y validar que los datos entrantes se ajusten a esa definición. Esta guía cubre todo, desde escribir tu primer Schema hasta patrones avanzados de validación compleja, con ejemplos prácticos que puedes aplicar inmediatamente.
Nuevo en Draft 2020-12. Soporta referencias dinámicas a Schemas.
JSON Schema es un documento JSON que describe la estructura y las restricciones de otros documentos JSON. Es un vocabulario que te permite anotar y validar datos JSON, estandarizado por el Internet Engineering Task Force (IETF). JSON Schema define reglas sobre qué campos deben existir, qué tipos deben tener, qué valores son aceptables y cómo deben estructurarse los objetos y arrays.
Piensa en JSON Schema como el contrato de tus datos. Así como un esquema de base de datos define las columnas, tipos y restricciones de una tabla, JSON Schema define las propiedades, tipos y restricciones de los documentos JSON. Cualquier dato JSON que cumpla todas las restricciones del Schema se llama instancia válida, mientras que los datos que violan cualquier restricción son inválidos.
OpenAPI (extensión)
- No es un formato de datos: JSON Schema no define cómo se serializan o transmiten los datos. Solo describe cómo se ven los datos válidos.
- No es un sustituto de la lógica de negocio: la validación Schema verifica la corrección estructural (tipos, formato, rangos). Las reglas de negocio complejas (como "un usuario no puede transferir más que su saldo") pertenecen al código de la aplicación.
- No es un esquema de base de datos: aunque conceptualmente similar, JSON Schema valida documentos JSON, no tablas de base de datos. Sin embargo, puedes usar JSON Schema junto con las restricciones de base de datos para una defensa en profundidad.
Hace referencia a un Schema desde un archivo externo.
JSON Schema ha evolucionado a través de múltiples borradores, cada uno agregando funcionalidades y refinando el vocabulario. Comprender estas versiones te ayuda a elegir la correcta para tu proyecto y evitar problemas de compatibilidad.
| Versión | $schema URI | Estado | Características principales |
|---|---|---|---|
| Draft 2020-12 | https://json-schema.org/draft/2020-12/schema | Versión actual | prefixItems, dynamicRef, soporte de vocabulario |
| Draft 2019-09 | https://json-schema.org/draft/2019-09/schema | Estable | unevaluatedProperties, $recursiveRef |
| Draft 7 | http://json-schema.org/draft-07/schema# | Ampliamente soportado | if/then/else, contentEncoding |
| Draft 6 | http://json-schema.org/draft-06/schema# | Legado | propertyNames, contains |
| Draft 4 | http://json-schema.org/draft-04/schema# | Obsoleto | Primera versión ampliamente adoptada |
sin espacio
Comencemos con un ejemplo simple: un Schema para un objeto de usuario con nombre, email y edad.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/user.json",
"title": "User",
"description": "A user account in the system",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "The user's full name"
},
"email": {
"type": "string",
"format": "email",
"description": "The user's email address"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150,
"description": "The user's age in years"
}
},
"required": ["name", "email"],
"additionalProperties": false
}Este Schema declara que un usuario válido debe ser un objeto donde name y email son propiedades de cadena requeridas. La propiedad age es opcional pero si está presente debe ser un entero entre 0 y 150. La restricción additionalProperties: false evita cualquier propiedad no definida en el Schema, lo que detecta errores tipográficos y campos inesperados.
con espacio (recomendado)
JSON Schema proporciona un rico vocabulario de palabras clave para definir restricciones. Aquí están las más importantes, organizadas por categoría.
Schema por defecto para todos los elementos del array.
| Palabras clave | Descripción | Ejemplo |
|---|---|---|
| type | Tipo de dato esperado | "type": "string" o "type": ["string", "null"] |
| enum | Lista de valores permitidos | "enum": ["active", "inactive", "pending"] |
| const | Debe ser igual a este valor exacto | "const": "v2" |
Valida por tipo de elemento.
| Palabras clave | Descripción | Ejemplo |
|---|---|---|
| minimum | Valor mínimo (inclusivo) | "minimum": 0 |
| exclusiveMinimum | Valor mínimo (exclusivo) | "exclusiveMinimum": 0 |
| maximum | Valor máximo (inclusivo) | "maximum": 100 |
| exclusiveMaximum | Valor máximo (exclusivo) | "exclusiveMaximum": 100 |
| multipleOf | Debe ser múltiplo de este valor | "multipleOf": 0.01 |
Verifica que los elementos del array sean únicos.
| Palabras clave | Descripción | Ejemplo |
|---|---|---|
| minLength | Longitud mínima de cadena | "minLength": 1 |
| maxLength | Longitud máxima de cadena | "maxLength": 255 |
| pattern | Expresión regular que la cadena debe coincidir | "pattern": "^[A-Z]{2}\\d{4}$" |
| format | Formato semántico (email, uri, date-time, etc.) | "format": "email" |
Verifica que el array tenga al menos un elemento.
| Palabras clave | Descripción | Ejemplo |
|---|---|---|
| properties | Schema para cada propiedad conocida | "properties": {"name": {"type": "string"}} |
| required | Lista de propiedades requeridas | "required": ["name", "email"] |
| additionalProperties | Si se permiten propiedades adicionales | "additionalProperties": false |
| minProperties | Número mínimo de propiedades | "minProperties": 1 |
| maxProperties | Número máximo de propiedades | "maxProperties": 10 |
| patternProperties | Schema para propiedades que coinciden con regex | "patternProperties": {"^S_": {"type": "string"}} |
Valida cada elemento contra todos los Schemas para detectar coincidencias.
| Palabras clave | Descripción | Ejemplo |
|---|---|---|
| items | Schema para todos los elementos del array | "items": {"type": "string"} |
| prefixItems | Schema para elementos posicionales (Draft 2020-12) | "prefixItems": [{"type": "string"}, {"type": "number"}] |
| minItems | Número mínimo de elementos | "minItems": 1 |
| maxItems | Número máximo de elementos | "maxItems": 100 |
| uniqueItems | Todos los elementos deben ser únicos | "uniqueItems": true |
Versión del Draft
Los Schemas del mundo real a menudo requieren patrones que van más allá de la simple verificación de tipos. Aquí están los patrones más utilizados.
if/then/else para validación condicional
Usa lógica condicional para aplicar diferentes restricciones según los valores de las propiedades. Por ejemplo, un objeto de pago requiere diferentes campos según el método de pago.
{
"type": "object",
"properties": {
"method": { "enum": ["credit_card", "bank_transfer"] },
"card_number": { "type": "string" },
"routing_number": { "type": "string" }
},
"required": ["method"],
"if": {
"properties": { "method": { "const": "credit_card" } }
},
"then": {
"required": ["card_number"]
},
"else": {
"required": ["routing_number"]
}
}allOf, anyOf, oneOf para composición
Las palabras clave de composición te permiten combinar Schemas de manera potente:
- allOf: Los datos deben satisfacer todos los sub-Schemas. Se usa para combinar múltiples restricciones o mezclar fragmentos de Schema reutilizables.
- anyOf: Los datos deben satisfacer al menos un sub-Schema. Se usa para tipos de unión donde múltiples formas son aceptables.
- oneOf: Los datos deben satisfacer exactamente un sub-Schema. Se usa para alternativas mutuamente excluyentes.
{
"oneOf": [
{
"type": "object",
"properties": {
"type": { "const": "email" },
"address": { "type": "string", "format": "email" }
},
"required": ["type", "address"]
},
{
"type": "object",
"properties": {
"type": { "const": "phone" },
"number": { "type": "string", "pattern": "^\\+?[1-9]\\d{1,14}$" }
},
"required": ["type", "number"]
}
]
}$ref para reutilización de Schema
La palabra clave $ref te permite referenciar y reutilizar Schemas, eliminando la duplicación y manteniendo los Schemas mantenibles. Puedes referenciar Schemas dentro del mismo documento o en archivos externos.
{
"$id": "https://example.com/schemas/order.json",
"type": "object",
"properties": {
"customer": { "$ref": "#/$defs/address" },
"shipping": { "$ref": "#/$defs/address" },
"billing": { "$ref": "#/$defs/address" },
"items": {
"type": "array",
"items": { "$ref": "#/$defs/lineItem" },
"minItems": 1
}
},
"required": ["customer", "items"],
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" },
"country": { "type": "string", "minLength": 2, "maxLength": 2 }
},
"required": ["street", "city", "zip", "country"]
},
"lineItem": {
"type": "object",
"properties": {
"product": { "type": "string" },
"quantity": { "type": "integer", "minimum": 1 },
"price": { "type": "number", "exclusiveMinimum": 0 }
},
"required": ["product", "quantity", "price"]
}
}
}Tipos nullable
En JSON Schema Draft 2020-12, los tipos nullable se expresan usando un array de tipos que incluye "null":
{
"type": ["string", "null"],
"description": "An optional display name, or null if not set"
}En borradores anteriores, la especificación OpenAPI usaba la palabra clave nullable: true. Para JSON Schema estándar, usa siempre el enfoque de array de tipos.
Sintaxis de nullable
La palabra clave format proporciona validación semántica más allá de la verificación estructural. Especifica que una cadena debe ajustarse a un formato conocido. Los formatos comúnmente soportados incluyen:
| Formato | Descripción | Ejemplo |
|---|---|---|
| Dirección de correo electrónico | user@example.com | |
| uri | URI válido | https://example.com/path |
| uri-reference | URI o referencia relativa | /path/to/resource |
| date-time | Fecha y hora ISO 8601 | 2026-05-19T14:30:00Z |
| date | Fecha ISO 8601 | 2026-05-19 |
| time | Hora ISO 8601 | 14:30:00Z |
| ipv4 | Dirección IPv4 | 192.168.1.1 |
| ipv6 | Dirección IPv6 | ::1 |
| uuid | Identificador único universal | 550e8400-e29b-41d4-a716-446655440000 |
| hostname | Nombre de host de Internet | www.example.com |
Draft 2020-12
La validación de Schema es más útil cuando se integra en el código de tu aplicación. Aquí hay ejemplos usando bibliotecas populares en diferentes lenguajes.
JavaScript con Ajv
Ajv es el validador JSON Schema más utilizado en JavaScript. Soporta todas las versiones de borrador y ofrece un rendimiento excelente a través de la compilación JIT de Schemas.
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const ajv = new Ajv();
addFormats(ajv);
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 0 }
},
required: ['name', 'email'],
additionalProperties: false
};
const validate = ajv.compile(schema);
const valid = validate({ name: 'Alice', email: 'alice@example.com', age: 30 });
if (!valid) {
console.log(validate.errors);
// [{ keyword: 'required', params: { missingProperty: 'email' }, ... }]
}Python con jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name", "email"],
"additionalProperties": False
}
try:
validate(instance={"name": "Alice", "email": "alice@example.com"}, schema=schema)
except ValidationError as e:
print(f"Validation failed: {e.message}")Draft 7 y anteriores
Una de las aplicaciones más valiosas de JSON Schema es validar datos de solicitud y respuesta de API. Esto asegura que tu API reciba entradas bien formadas y devuelva datos en el formato esperado, detectando errores temprano y proporcionando mensajes de error claros a los clientes.
Middleware de Express.js
import Ajv from 'ajv';
const ajv = new Ajv({ allErrors: true });
function validateBody(schema) {
const validate = ajv.compile(schema);
return (req, res, next) => {
if (!validate(req.body)) {
return res.status(400).json({
error: 'Validation failed',
details: validate.errors
});
}
next();
};
}
app.post('/api/users',
validateBody({
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
email: { type: 'string', format: 'email' },
role: { enum: ['admin', 'editor', 'viewer'] }
},
required: ['name', 'email'],
additionalProperties: false
}),
(req, res) => {
// req.body is guaranteed valid here
createUser(req.body);
}
);OpenAPI y JSON Schema
OpenAPI (anteriormente Swagger) utiliza un subconjunto de JSON Schema para definir los Schemas de solicitud y respuesta de API. Si ya estás usando OpenAPI, puedes extraer Schemas de tu especificación API y usarlos para validación en tiempo de ejecución. Herramientas como openapi-schema-validator y express-openapi-validator pueden automatizar este proceso, asegurando que tu documentación API y lógica de validación permanezcan siempre sincronizadas.
Draft 4
- Siempre establece $schema: Incluye la palabra clave $schema para declarar qué versión de borrador usa tu Schema. Esto previene ambigüedades y asegura que los validadores interpreten tu Schema correctamente.
- Usa $id para identificación de Schema: La palabra clave $id proporciona un identificador único para tu Schema y sirve como URI base para resolver referencias $ref. Siempre configúrala, incluso para Schemas locales.
- Establece additionalProperties: false: Por defecto, JSON Schema permite cualquier propiedad adicional en los objetos. Establecer additionalProperties: false detecta errores tipográficos y campos inesperados, haciendo tu Schema más estricto y tu API más predecible.
- Usa $defs para componentes reutilizables: Define Schemas comunes en $defs y refiérete a ellos usando $ref. Esto reduce la duplicación y hace que los Schemas sean más fáciles de mantener.
- Agrega descripciones: Cada propiedad y Schema debe tener un campo description. Esto sirve como documentación y ayuda a otros desarrolladores a entender el propósito y las restricciones de cada campo.
- Valida en los límites del sistema: Aplica la validación Schema en los bordes de tu sistema: endpoints API, consumidores de mensajes, tuberías de importación de datos y cargadores de configuración. No valides datos que tu propio código ya ha producido y en los que confías.
- Habilita el modo estricto en los validadores: Configura tu validador para rechazar palabras clave desconocidas, forzar la validación de formatos y reportar todos los errores en lugar de detenerse en el primero. Esto captura más problemas en una sola pasada de validación.
- Versiona tus Schemas: Incluye la versión del Schema en el URI $id (por ejemplo, https://example.com/schemas/user/v2.json). Esto te permite evolucionar los Schemas sin romper los consumidores existentes.
- Prueba tus Schemas: Escribe pruebas unitarias para tus Schemas con ejemplos válidos e inválidos. Esto asegura que tu Schema aplique las restricciones que pretendes y detecta regresiones cuando los Schemas se modifican.
- Usa format para validación semántica: Prefiere format: "email" sobre patrones regex complejos. Los formatos son más legibles, más mantenibles y se benefician de la lógica de validación bien probada en las bibliotecas validadoras.
¿Necesitas validar datos JSON contra un Schema? Prueba nuestro validador JSON Schema en línea gratuito. Pega tu Schema y tus datos para obtener resultados de validación instantáneos con mensajes de error detallados.
Validador JSON SchemaHerramienta de formato JSONPreguntas frecuentes
Nuevo en Draft 2020-12. Soporta referencias dinámicas a Schemas.
JSON Schema es un documento JSON que describe la estructura y las restricciones de otros documentos JSON. Te permite definir campos requeridos, tipos de datos esperados, rangos de valores, patrones de cadena y estructuras de objetos anidados. Puedes usarlo para validar datos entrantes, generar documentación y crear automáticamente interfaces de formulario.
¿Qué versión de JSON Schema debería usar?
Para nuevos proyectos, usa JSON Schema Draft 2020-12. Es la última versión estable y está soportada por los principales validadores como Ajv. Si necesitas compatibilidad con herramientas más antiguas, Draft 7 también tiene soporte generalizado. Evita Draft 4 y versiones anteriores ya que usan palabras clave obsoletas y carecen de funcionalidades modernas.
¿Cuál es la diferencia entre JSON Schema y las interfaces de TypeScript?
Las interfaces de TypeScript solo proporcionan verificación de tipos en tiempo de compilación dentro del código TypeScript. JSON Schema proporciona validación en tiempo de ejecución a través de lenguajes de programación, pudiendo validar datos de cualquier fuente (solicitudes API, archivos, bases de datos). Usa TypeScript para seguridad en tiempo de desarrollo y JSON Schema para validación de datos en tiempo de ejecución en los límites del sistema.
¿Puede JSON Schema validar cuerpos de solicitud API?
Sí, JSON Schema se usa ampliamente para la validación de solicitudes y respuestas API. Frameworks como Express (con express-json-validator), FastAPI y Spring Boot soportan la validación JSON Schema de forma nativa o a través de middleware. Validar los cuerpos de solicitud contra un Schema asegura que los datos entrantes tengan la estructura correcta antes de que tu aplicación los procese.
¿Cuáles son las palabras clave más importantes de JSON Schema?
Las palabras clave más críticas son: type (tipo de dato), properties (campos de objeto), required (campos obligatorios), items (Schema de elementos de array), minimum/maximum (límites numéricos), minLength/maxLength (límites de cadena), pattern (regex de cadena), enum (valores permitidos) y $ref (referencia para reutilizar Schemas). Estas palabras clave cubren la gran mayoría de las necesidades de validación.