Campos opcionales de un acta: tratarlos como ausentes
Que un dato haya llegado siempre no es una promesa del contrato. Si el consumidor no escribe la rama del campo que falta, la ausencia termina disfrazada de cero, de fecha vacía o de “sin deuda”.
Por Marco Ferreiro ·
Pensá en una integración de flota que leyó vencimiento durante meses y armó alertas con ese dato. Si una jurisdicción deja de publicarlo, la respuesta sigue siendo válida —el campo era opcional— y simplemente no viene. El código no falla: la fecha queda sin valor y las alertas de esa jurisdicción dejan de dispararse. Nadie ve un error, sino una pantalla tranquila.
Ese es el riesgo de fondo. Un campo opcional de un acta es un permiso que el productor se reserva —puede omitirlo—, no una estimación de cuán seguido va a estar. Por eso conviene invertir el valor por defecto: asumir que no llega y tratar su presencia como el caso extra.
Esta nota mira el lado de quien consume. La diferencia entre null, cero y ausencia dentro del contrato está en null, campo ausente o cero.
Opcional es un permiso, no una probabilidad
En JSON Schema describir una propiedad no la vuelve exigible: la presencia se declara con la lista de propiedades obligatorias, y lo que no figura ahí puede faltar en cualquier respuesta. Que hoy venga siempre es una observación sobre las jurisdicciones de hoy, no una cláusula.
En consultas de infracciones hay motivos cotidianos para que un atributo desaparezca: una jurisdicción deja de publicarlo; una fuente responde degradada y la respuesta se arma con lo que hay; la representación es un resumen y no el detalle.
Del lado de la solicitud pasa lo mismo. En OpenAPI un parámetro es opcional salvo que se lo marque obligatorio —en la ruta el estándar exige que lo sea—, y si omitís uno lo que tu integración usa es el comportamiento del servidor para ese caso, que puede cambiar sin romper el esquema. Si te importa, mandalo explícito.
Un esquema no restringe lo que no llegó
La palabra clave que describe las propiedades de un objeto alcanza a los nombres que aparecen a la vez en la instancia y en el esquema: si la propiedad no está, su subesquema no se evalúa y la validación pasa igual.
required: [actaId, jurisdiccion]
properties:
vencimiento:
type: string
format: date
monto:
type: number
minimum: 0
Con ese esquema, una respuesta que trae sólo actaId y jurisdiccion es válida: ni el formato de vencimiento ni el mínimo de monto llegan a evaluarse, simplemente porque no hay valor sobre el cual hacerlo.
Un validador en verde dice que la forma es admisible, no que el dato esté. Comprobar la presencia de lo que te importa sigue siendo tarea tuya.
Escribí primero la rama de la ausencia
La rama de la ausencia es el camino que corre cuando el campo no vino, y suele ser el último que alguien escribe. Conviene escribirlo primero y que sea conservador.
Lo que no hay que hacer es rellenar. Cero en un monto que no llegó, la fecha de hoy en un vencimiento vacío o “vigente” en el estado de un acta que nadie informó convierten desconocimiento en afirmación.
Tres consecuencias:
- en el modelo interno, ausencia y valor tienen que seguir siendo distinguibles después de deserializar;
- en la pantalla y en el reporte, “no informado” se escribe, no se deja en blanco;
- en las reglas de negocio, ninguna condición debería cumplirse por omisión.
Toda decisión que dependa de un campo opcional debería declarar qué hace sin él: postergar, escalar o marcar el caso como no evaluable.
Eso se prueba con un fixture de payload mínimo —sólo los campos obligatorios— y uno por cada opcional ausente, corriendo el flujo entero y no sólo el parseo: exportación, reporte, alerta y agregado. Los tests de contrato son el lugar natural para fijarlos.
Dónde se borra la diferencia
La ausencia no es un valor, así que no compara. Un filtro por vencimiento anterior a cierta fecha excluye en silencio a las actas que no lo tienen; un ordenamiento tiene que declarar dónde los ubica; un promedio necesita publicar su denominador: la cantidad de registros con el campo, no el total.
En las exportaciones la diferencia se pierde del todo. El formato CSV espera que todas las líneas tengan la misma cantidad de campos, así que la columna existe siempre y la ausencia se convierte en una celda vacía, indistinguible de un texto vacío y expuesta a que la planilla o el importador la lean como cero. Si el archivo de multas alimenta una decisión, agregá una columna de estado junto al dato o un valor centinela documentado.
Qué revisar antes de integrar
- pedí la lista de campos opcionales y, para cada uno, bajo qué condiciones puede faltar;
- confirmá si “opcional” significa que puede venir ausente, en null, o ambas;
- probá qué hace tu deserializador con un campo faltante en cada lenguaje;
- buscá en tu código los valores por defecto que hoy tapan una ausencia;
- sumá el payload mínimo a la suite y verificá que ninguna salida afirme algo que no fue informado.
Un contrato con pocos opcionales, y bien documentados, es más barato de consumir: cada campo que puede faltar es una rama que alguien tiene que escribir. Mientras esa rama no exista, el sistema no está tolerando la ausencia; la está tapando.
Metodología
- Alcance
- Cómo debería tratar un consumidor los campos declarados opcionales en una respuesta de infracciones y qué revisar antes de integrar. No define la semántica de null frente a cero ni audita el contrato de un proveedor en particular.
- Unidad de análisis
- Un campo opcional del contrato y la decisión que toma el consumidor cuando ese campo no llega en la respuesta.
- Cobertura
- Reglas de presencia y validación de JSON Schema 2020-12, declaración de campos y parámetros obligatorios en OpenAPI 3.1 y el formato CSV usado en exportaciones, al 29 de agosto de 2026.
Limitaciones
- Los fragmentos de esquema son ilustrativos y no representan el contrato vigente de multas.ar ni el de una jurisdicción real.
- Cada generador de clientes mapea distinto la ausencia y el valor nulo; ese comportamiento hay que verificarlo en el lenguaje que se use.
- La nota no reemplaza la documentación del proveedor sobre las condiciones bajo las cuales cada campo puede faltar.
Fuentes
- JSON Schema Core 2020-12 — JSON Schema (consultada el )
- JSON Schema Validation Draft 2020-12 — JSON Schema (consultada el )
- OpenAPI Specification version 3.1.2 — OpenAPI Initiative (consultada el )
- RFC 4180: Common Format and MIME Type for CSV Files — RFC Editor (consultada el )
Preguntas frecuentes
¿Un campo que llegó siempre puede dejar de llegar?
Sí, si el contrato lo declara opcional. La lista de propiedades obligatorias es lo que compromete al productor; todo lo que queda afuera puede omitirse en cualquier respuesta, sin cambiar la versión y sin aviso previo.
¿Validar contra el esquema garantiza que el campo llegó?
No. Las restricciones definidas para una propiedad se evalúan sólo si esa propiedad está presente en la instancia. Un objeto sin el campo opcional pasa la validación igual, así que un validador en verde confirma que la forma es admisible, no que el dato esté.
¿Está bien completar con cero cuando un campo opcional no viene?
No conviene. Cero, la fecha de hoy o un estado supuesto convierten un desconocimiento en una afirmación, y en infracciones esa afirmación puede terminar como “sin deuda” o “sin vencimiento” en un reporte. La ausencia debería seguir siendo visible en el modelo y en la salida.
Notas relacionadas
Null, campo ausente o cero: tres respuestas distintas en un contrato de infracciones
Un monto cero es un número, null es un valor explícito y un campo ausente no fue enviado. Si el contrato los mezcla, un cliente puede informar que no hay deuda cuando sólo falta un dato.
Cómo versionar una respuesta cuando cada jurisdicción cambia
Una respuesta agregada necesita distinguir versión de contrato, revisión de datos y estado de cada fuente. Así un cambio municipal no obliga a reinterpretar silenciosamente todo el resultado.
Verificar que el informe de multas descargado llegó completo
Un HTTPS exitoso no prueba que el archivo almacenado sea el esperado. Tamaño, revisión y digest permiten detectar truncamientos o cambios antes de importarlo.