Saltar al contenido principal
Volver al inicio

¿Qué es APEX_JSON y por qué deberías usarlo desde ya?

24 de mayo de 20266 min de lectura5 vistas

Introducción

Si trabajás con Oracle APEX hace más de cinco minutos, ya sabés que JSON está en todas partes. Las APIs REST lo usan, los servicios web modernos lo hablan, y cada vez más las apps APEX necesitan tanto generar JSON para consumidores externos como parsear JSON que viene de afuera. El problema es que mucha gente resuelve esto de la manera más peligrosa posible: concatenando strings.

Si alguna vez escribiste algo como l_json := '{"nombre": "' || v_nombre || '"}';, este artículo es para vos. Ese patrón parece inofensivo hasta que el nombre contiene una comilla (O'Brien), una barra invertida, o un salto de línea — y ahí el JSON queda malformado silenciosamente, o peor, se convierte en un vector de inyección.

En esta primera entrega de la serie vamos a ver qué es APEX_JSON, desde cuándo está disponible, qué problemas resuelve y cómo empezar a usarlo hoy mismo sin necesidad de ninguna instalación adicional.

Qué es APEX_JSON y desde qué versión está disponible

APEX_JSON es un package PL/SQL que viene incluido con Oracle APEX desde la versión 5.0 (lanzada en 2015). No es una librería externa, no requiere ningún CREATE TYPE especial ni dependencias adicionales: si tenés APEX instalado, ya tenés APEX_JSON.

El package vive en el schema APEX_050000 (o el schema correspondiente a tu versión de APEX) y está disponible con grant público, así que cualquier usuario de la base de datos puede invocarlo directamente desde un bloque PL/SQL anónimo, un procedimiento almacenado, o un proceso de APEX.

A lo largo de las versiones, Oracle fue ampliando el package. En APEX 5.1 se agregaron mejoras en el manejo de tipos, en APEX 18+ se consolidaron las sobrecargas para trabajar con CLOB sin complicaciones, y en versiones más recientes se sumaron utilidades para integración con ORDS. La interfaz básica, sin embargo, se mantiene consistente desde APEX 5 — lo que aprendás hoy va a funcionar igual en producción aunque tu cliente tenga una versión antigua.

Por qué usarlo en lugar de concatenar strings JSON a mano

El argumento más importante para adoptar APEX_JSON no es la comodidad — es la corrección.

Cuando concatenás strings para armar JSON, estás asumiendo que todos los valores son "seguros". En la práctica, los datos vienen de usuarios, de otras tablas, de APIs externas. Cualquier string que contenga ", \, /, caracteres de control (tab, newline, carriage return) o incluso caracteres Unicode fuera del rango ASCII puede romper el JSON resultante.

APEX_JSON.write escapa automáticamente todos esos caracteres según el estándar JSON (RFC 8259). No tenés que pensar en eso, no tenés que escribir una función de escape propia, no tenés que acordarte de los casos borde. El package lo hace por vos, siempre.

Hay además un beneficio de mantenibilidad: el código que usa APEX_JSON es legible como estructura. Cuando ves una secuencia de open_object, write, open_array, close_array, close_object, podés visualizar el JSON resultante sin ejecutar nada. Cuando ves una concatenación de 20 líneas, tenés que rastrear cada || para entender qué forma tiene el JSON.

Los dos grandes grupos de funciones

El package APEX_JSON se divide claramente en dos responsabilidades:

Generación de JSON — para cuando necesitás producir JSON a partir de datos PL/SQL. Las funciones principales son:

  • open_object / close_object — delimitan un objeto JSON {}

  • open_array / close_array — delimitan un array JSON []

  • write — escribe un par clave-valor (o un valor simple en un array)

  • write_raw — incrusta JSON ya formateado sin re-escapar

  • initialize_clob_output / get_clob_output / free_output — para manejar salidas grandes como CLOB

Parseo de JSON — para cuando recibís JSON y necesitás extraer valores. Las funciones principales son:

  • parse — lee un string o CLOB JSON y lo descompone en un tipo interno t_values

  • get_varchar2, get_number, get_date, get_boolean — extraen valores por path

  • get_count — cuenta elementos de un array

  • does_exist — verifica si un campo existe antes de leerlo

  • get_members — lista las claves de un objeto dinámico

Estas dos familias no son independientes: en artículos siguientes vamos a ver cómo combinar parseo + generación para transformar un JSON entrante en otro JSON saliente, que es un patrón muy común en integraciones.

Cuándo conviene APEX_JSON vs las funciones nativas JSON de Oracle 12c+

Oracle 12c introdujo soporte nativo para JSON en la capa SQL: JSON_VALUE, JSON_QUERY, JSON_TABLE, IS JSON, y el tipo JSON en Oracle 21c+. Es una pregunta legítima preguntarse cuándo usar uno u otro.

La respuesta práctica es: usalos juntos según el contexto.

Las funciones nativas de Oracle brillan cuando trabajás con columnas JSON almacenadas en tablas. Si tenés una columna CLOB con JSON y querés hacer queries sobre ella, JSON_TABLE con un CROSS JOIN es probablemente la mejor herramienta. También son más eficientes para filtering en SQL porque el optimizer puede aprovechar índices funcionales sobre paths JSON.

APEX_JSON brilla cuando estás en código PL/SQL y necesitás generar o parsear JSON de forma programática: construir una respuesta para un endpoint, procesar una respuesta de una API REST, o transformar un REF CURSOR en JSON. También es tu única opción si tu ambiente corre Oracle 11g o APEX sin las extensiones JSON de 12c.

Una decisión que funciona bien en la práctica: usá JSON_TABLE para cargar/consultar JSON en SQL, y usá APEX_JSON para generar JSON en PL/SQL. No tenés que elegir uno solo.

Setup mínimo para practicar

No necesitás una aplicación APEX corriendo para practicar APEX_JSON. Alcanza con un bloque PL/SQL anónimo en SQL Workshop → SQL Commands (si estás en APEX) o en SQL*Plus / SQL Developer / LiveSQL.

Y con eso ya podés ejecutar el ejemplo más básico del package:

DECLARE
    l_output CLOB;
BEGIN
    APEX_JSON.initialize_clob_output;   -- inicializar buffer explícito

    APEX_JSON.open_object;
        APEX_JSON.write('nombre', 'Cristhian');
        APEX_JSON.write('ciudad', 'Yhu');
    APEX_JSON.close_object;

    l_output := APEX_JSON.get_clob_output;
    APEX_JSON.free_output;

    DBMS_OUTPUT.put_line(l_output);
END;

Fijate que no hace falta ninguna declaración especial, ninguna inicialización, ningún contexto de APEX activo. El package por defecto escribe directo a DBMS_OUTPUT. En artículos siguientes vamos a ver cómo redirigir esa salida a un CLOB cuando necesitamos la cadena en una variable, pero para arrancar con DBMS_OUTPUT es suficiente.

Tip: Si el output aparece sin espacios ni saltos de línea (JSON compacto), es el comportamiento normal. `APEX_JSON` genera JSON minificado por defecto. Podés formatear el output con herramientas como `jq` o cualquier formateador online si querés leerlo más cómodamente durante el desarrollo.

Conclusión

APEX_JSON es el camino correcto para manejar JSON desde PL/SQL en aplicaciones APEX. Es seguro, predecible, está disponible sin configuración y su API es lo suficientemente simple para aprenderla en una tarde. El único costo es abandonar el hábito de concatenar strings — y ese es un hábito que vale la pena perder.

En el próximo artículo vemos cómo generar JSONs complejos — objetos anidados, arrays y hasta un REF CURSOR convertido en JSON en una sola línea.

Artículos relacionados