Los parámetros de API a menudo tienen estructuras complejas, con un único endpoint que soporta múltiples combinaciones de parámetros diferentes. Por ejemplo, un endpoint de inicio de sesión podría soportar autenticación por nombre de usuario y contraseña, autenticación por correo electrónico y contraseña, o códigos de verificación por número de teléfono. Los endpoints de pago pueden ofrecer varios métodos como tarjetas de crédito, WeChat Pay o Alipay, cada uno requiriendo campos diferentes.

Los enfoques tradicionales de documentación de API a menudo simplemente enumeran todos los campos posibles y usan descripciones de texto como "elegir diferentes campos según diferentes escenarios". Este enfoque no es preciso ni amigable para el desarrollador, lo que a menudo lleva a confusión. Apidog soporta las características oneOf, anyOf y allOf de JSON Schema, lo que te permite describir con precisión estas complejas estructuras de datos compuestas en tu documentación de API.
Comprendiendo los Tres Modos de Combinación
En JSON Schema, oneOf, anyOf y allOf se utilizan para combinar múltiples subesquemas, pero tienen diferentes significados lógicos:
- allOf: Combina múltiples reglas, requiriendo que todas coincidan.
- anyOf: Se requiere al menos una coincidencia, se aceptan múltiples coincidencias.
- oneOf: Debe coincidir exactamente con un esquema; si coincide con cero o múltiples esquemas, fallará.
Configuración de Modos de Combinación en Apidog
Apidog ofrece dos formas de usar estos modos de combinación:
Enfoque del Editor Visual
El primer método utiliza el panel de edición visual. En tu proyecto, haz clic en "Modelos de Datos" para crear un nuevo modelo, luego busca "Modos de Combinación" en la selección de tipo. Elige el modo oneOf, anyOf o allOf necesario, luego define estructuras de datos específicas para cada subesquema.

Editor de Código JSON Schema
El segundo enfoque implica editar directamente el código JSON Schema. En el panel de edición del modelo de datos, puedes cambiar al modo de código y escribir JSON Schema directamente para definir estos patrones de combinación lógica. Este método es más directo para los desarrolladores familiarizados con JSON Schema.

Aplicando Estos Patrones en Endpoints de API
Una vez que hayas definido tus modelos de datos, puedes usarlos en tu documentación de API. Al editar los parámetros de solicitud de la interfaz, selecciona el tipo de Cuerpo como JSON, luego en la sección de estructura de datos, puedes hacer referencia a los "Modelos de Datos" que acabas de crear, o seleccionar directamente "Modos de Combinación" para definir estructuras de parámetros complejas.

El mismo principio se aplica a las definiciones de datos de respuesta. Al añadir ejemplos de respuesta en la sección de respuesta de retorno, puedes usar modos de combinación para describir los formatos de respuesta para diferentes escenarios. De esta manera, los desarrolladores pueden comprender claramente qué estructura de datos se devolverá en diferentes situaciones.
Casos de Uso en el Mundo Real
allOf: Combinando Múltiples Estructuras
allOf combina múltiples estructuras juntas; no se trata de selección, sino de apilamiento. allOf no cambia la jerarquía de los campos; todos los campos terminan en el mismo objeto. Simplemente apila múltiples reglas sobre los mismos datos. Piénsalo como un "AND lógico": todas las restricciones de la subestructura deben cumplirse.
Por ejemplo, este JSON Schema:
{
"allOf": [
{
"description": "Información básica del usuario",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"]
},
{
"description": "Información de contacto",
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"phone": { "type": "string" }
},
"required": ["email"]
}
]
}
Este esquema significa: los datos finales deben satisfacer simultáneamente tanto la estructura de "información básica del usuario" como la de "información de contacto".
En otras palabras, el cuerpo de la solicitud debe incluir id, name y email, mientras que phone es opcional.
Datos válidos:
{
"id": 1001,
"name": "John Doe",
"email": "john@example.com",
"phone": "1-800-000-0000"
}
Datos inválidos:
{
"id": 1001,
"name": "John Doe"
}
A esto le falta el campo de correo electrónico requerido y no satisface la segunda estructura.
Este enfoque es adecuado para dividir objetos complejos. La información del usuario, los detalles del pedido, los elementos de configuración, etc., pueden dividirse en estructuras independientes por módulos funcionales y luego combinarse usando allOf. Otras interfaces que necesiten parte de estas estructuras pueden referenciarlas directamente sin definiciones redundantes.
anyOf: Satisfaciendo al Menos Una Condición
anyOf enumera múltiples estructuras posibles, y los datos se consideran válidos siempre que se ajusten a al menos una de ellas. No le importa si se cumplen múltiples condiciones, ni requiere una coincidencia única.
Por ejemplo, un campo de identificador podría ser un correo electrónico o un número de teléfono. Estos dos formatos son claramente diferentes, pero ambos pertenecen a la categoría de "credenciales de inicio de sesión de usuario".
Puedes usar anyOf para expresar claramente esta intención de "puede ser A o B":
{
"type": "object",
"properties": {
"identifier": {
"description": "Identificador de usuario: puede ser correo electrónico o número de teléfono",
"anyOf": [
{
"title": "Formato de correo electrónico",
"description": "Debe ser una dirección de correo electrónico válida",
"type": "string",
"format": "email"
},
{
"title": "Formato de teléfono",
"description": "Debe ser un número de teléfono internacional válido",
"type": "string",
"pattern": "^\\+?[1-9]\\d{1,14}$"
}
]
},
"password": {
"type": "string",
"minLength": 6,
"description": "Contraseña de inicio de sesión, al menos 6 caracteres"
}
},
"required": ["identifier", "password"],
"description": "Parámetros de solicitud de inicio de sesión de usuario"
}
Esta estructura significa: el identificador es una cadena que se considera válida siempre que satisfaga el formato de correo electrónico o el formato de número de teléfono.
Datos válidos:
{
"identifier": "test@example.com",
"password": "123456"
}
{
"identifier": "+1-800-000-0000",
"password": "123456"
}
Datos inválidos:
{
"identifier": "abc",
"password": "123456"
}
"abc" no es un correo electrónico ni un formato de número de teléfono válido, no satisface ninguna de las condiciones.
oneOf: Elegir Exactamente Una Opción
oneOf enumera múltiples estructuras posibles, y los datos deben ajustarse exactamente a una de ellas. Enfatiza la exclusividad: solo puedes elegir una, ni más, ni menos.
Por ejemplo, métodos de pago: para completar un pago, los usuarios deben elegir una de las opciones (tarjeta de crédito, WeChat Pay o Alipay), pero no pueden usar dos métodos simultáneamente, ni tampoco pueden no elegir ninguno. Puedes definir esta lógica de "selección única" usando oneOf:
{
"properties": {
"paymentMethod": {
"description": "Método de pago, debe elegir exactamente uno",
"oneOf": [
{
"title": "Pago con Tarjeta de Crédito",
"description": "Pagar con tarjeta de crédito, requiere número de tarjeta y fecha de vencimiento",
"type": "object",
"properties": {
"type": { "const": "credit_card" },
"cardNumber": { "type": "string" },
"expiryDate": { "type": "string" }
},
"required": ["type", "cardNumber", "expiryDate"],
"additionalProperties": false
},
{
"title": "Pago con WeChat",
"description": "Pagar a través de WeChat, requiere el openid del usuario",
"type": "object",
"properties": {
"type": { "const": "wechat" },
"openid": { "type": "string" }
},
"required": ["type", "openid"],
"additionalProperties": false
},
{
"title": "Pago con Alipay",
"description": "Pagar a través de Alipay, requiere el ID de la cuenta",
"type": "object",
"properties": {
"type": { "const": "alipay" },
"accountId": { "type": "string" }
},
"required": ["type", "accountId"],
"additionalProperties": false
}
]
}
}
}
Esta definición significa: paymentMethod es un objeto que solo puede coincidir con una de las tres subestructuras.
Ejemplos válidos:
{
"paymentMethod": {
"type": "wechat",
"openid": "wx_123456"
}
}
{
"paymentMethod": {
"type": "credit_card",
"cardNumber": "4111111111111111",
"expiryDate": "12/25"
}
}
Ejemplo inválido:
{
"paymentMethod": {
"type": "wechat",
"openid": "wx_123",
"accountId": "2088102"
}
}
Aunque el tipo es "wechat", la presencia de accountId podría hacer que coincida con múltiples estructuras, causando que oneOf falle. Añadir "additionalProperties": false previene esta confusión (lo que significa que no se permiten campos adicionales), asegurando que cada estructura solo permita sus propios campos definidos. Apidog soporta la configuración visual para additionalProperties.
Cuando necesitas hacer elecciones exclusivas entre múltiples tipos distintos, oneOf es la forma más directa y confiable de expresar esto.
Eligiendo el Modo de Combinación Correcto
La elección del modo de combinación depende principalmente de tu lógica de negocio:
- Usa allOf cuando necesites combinar y heredar múltiples patrones.
- Usa anyOf cuando necesites combinaciones opcionales flexibles.
- Usa oneOf cuando necesites opciones exclusivas estrictas.
Comprender sus respectivos roles permite que tu documentación de API describa con precisión estructuras de datos complejas, dejando claro de inmediato a los usuarios de la interfaz cómo pasar los parámetros.
Conclusión
El soporte integral de Apidog para JSON Schema permite a los desarrolladores crear documentación de API precisa y clara, incluso para las estructuras de parámetros más complejas. Al aprovechar las combinaciones oneOf, anyOf y allOf, puedes eliminar la ambigüedad y proporcionar una guía cristalina a los consumidores de API.
¿Listo para experimentar el poder de la documentación de API avanzada? Prueba Apidog hoy mismo y descubre lo fácil que resulta gestionar parámetros de API complejos con precisión y claridad.
