DEV Community

Vinicio Jiménez
Vinicio Jiménez

Posted on • Originally published at insightsapex.hashnode.dev

Buenas Prácticas PL/SQL para Backends: Arquitectura sobre Sintaxis

Buenas Prácticas PL/SQL para Backends

🇺🇸 Read in English

Deja de construir monolitos atados a la página

💡 "Seguro por defecto no significa seguro por diseño." En el ecosistema de
Oracle APEX, esta realidad suele ignorarse en favor de la velocidad del
'low-code'. La frase más peligrosa en un proyecto de APEX es: "Solo pondré
esta lógica en un Proceso de Página por ahora".

Si tu lógica de negocio vive dentro de los Procesos de Página, no estás
construyendo una aplicación; estás construyendo un castillo de naipes. Algún día
necesitarás esa lógica para una API REST, un trabajo en segundo plano o una
página pública, y te encontrarás atrapado en un ciclo de duplicación y deuda
técnica.

En este artículo, no discutiremos sintaxis básica. Nos sumergiremos en los
patrones arquitectónicos que separan a los simples "creadores de páginas" de
los ingenieros de software.


La Trampa del Monolito: El fracaso impulsado por la UI

El principal desafío en APEX no es escribir el código; es dónde lo pones.
Cuando la lógica está fuertemente acoplada a la interfaz de usuario:

  • Probar es imposible: No puedes ejecutar un Proceso de Página desde un framework de pruebas unitarias como utPLSQL.
  • La seguridad se fragmenta: Cada página debe re-validar las mismas reglas de negocio, lo que lleva a una seguridad "con fugas".
  • El mantenimiento es una pesadilla: Un simple cambio en una regla fiscal requiere buscar en docenas de componentes de página diferentes.

Para solucionar esto, debemos cambiar nuestra perspectiva: la aplicación APEX
es solo una vista. La base de datos es la aplicación.


Modelos Mentales: La Capa de Servicio

Los backends profesionales se construyen en capas. Olvida los acrónimos
académicos; piensa en la responsabilidad:

  1. APEX es un Consumidor: Trata las páginas de APEX como envolturas delgadas y "tontas" alrededor de una API de PL/SQL.
  2. Servicios de Datos: Paquetes que son "dueños" de una tabla. Manejan DML, auditoría e integridad de bajo nivel.
  3. Módulos de Negocio: Paquetes que orquestan los "Servicios de Datos" para cumplir con un requisito de negocio (por ejemplo, "Alta de un Cliente").

⚠️ Regla de Oro: si no puedes ejecutar tu proceso de negocio principal desde
un prompt de SQL (SQL Developer/Línea de comandos) sin abrir el Page Designer de
APEX, tu arquitectura está rota.


Patrones Estratégicos: Modularización de la Lógica

1. Servicios de Datos (Los Guardianes)

Un Servicio de Datos encapsula todas las operaciones DML para una sola tabla.
Asegura que, sin importar quién modifique los datos, las reglas (como la
auditoría) siempre se apliquen.

Ejemlo (Servicio de Datos):

CREATE OR REPLACE PACKAGE order_data_svc AS
    PROCEDURE create_order (
        p_customer_id IN orders.customer_id%TYPE,
        p_status      IN orders.status%TYPE DEFAULT 'NEW'
    );
END order_data_svc;
Enter fullscreen mode Exit fullscreen mode

2. Módulos de Negocio (Los Orquestadores)

Un Módulo de Negocio maneja las reglas complejas. Llama a múltiples Servicios de
Datos y asegura que la transacción sea válida.

Diagrama de Flujo de Implementación:

graph TD
    UI[APEX UI / REST API] --> BM[Módulo de Negocio: Procesar Orden]
    BM --> DS1[Servicio de Datos: Órdenes]
    BM --> DS2[Servicio de Datos: Inventario]
    DS1 --> DB[(Base de Datos)]
    DS2 --> DB
Enter fullscreen mode Exit fullscreen mode

Cerrando la Brecha: Integración con la UI de APEX

Un temor común al mover la lógica a paquetes es perder los mensajes de error
"bonitos" en la interfaz. No tienes que elegir. Usa apex_error para cerrar la
brecha.

Ejemplo de Módulo de Alto Nivel:

PROCEDURE process_onboarding (p_user_id IN NUMBER) IS
BEGIN
    -- Verificación de Negocio
    IF user_has_pending_tasks(p_user_id) THEN
        apex_error.add_error (
            p_message          => 'El usuario tiene tareas pendientes ' ||
                                  'y no puede ser dado de alta.',
            p_display_location => apex_error.c_inline_with_field_and_notif,
            p_page_item_name   => 'P10_USER_ID'
        );
        RETURN;
    END IF;

    -- Continuar con la lógica...
END;
Enter fullscreen mode Exit fullscreen mode

Esto mantiene tu interfaz receptiva mientras mantienes tu lógica donde
pertenece: en la base de datos.


Seguridad Proactiva: Confía en el Contexto

Deja de pasar v('APP_USER') como parámetro a cada procedimiento. Es ruidoso y
propenso a la manipulación. En su lugar, usa SYS_CONTEXT dentro de tus
Servicios de Datos para automatizar la auditoría.

-- Dentro de tu procedimiento de Servicio de Datos
INSERT INTO orders (..., created_by) 
VALUES (..., COALESCE(sys_context('APEX$SESSION', 'APP_USER'), USER));
Enter fullscreen mode Exit fullscreen mode

✅ Esto asegura que la auditoría funcione ya sea que la llamada provenga de una
página de APEX, un servicio REST o un script de migración.


Ingeniería Técnica: Rendimiento a Escala

1. Blindaje Dinámico con DBMS_ASSERT

Al escribir SQL dinámico para reportes flexibles, nunca confíes en la entrada
del usuario.

-- BIEN: Usando DBMS_ASSERT para sanear nombres de tablas en código dinámico
l_sql := 'SELECT count(*) FROM ' || sys.dbms_assert.enquote_name(l_table_name);
Enter fullscreen mode Exit fullscreen mode

2. Procesamiento por Lotes de Alto Rendimiento

Para procesos de backend, deja de usar bucles de cursor y comienza a usar
BULK COLLECT y FORALL.

-- BIEN: Procesamiento masivo para rendimiento
FORALL i IN 1..l_ids.COUNT
    UPDATE employee_stats 
       SET salary = salary * 1.1 
     WHERE emp_id = l_ids(i);
Enter fullscreen mode Exit fullscreen mode

Checklist del Consultor: El Filtro para Producción

Valida tu backend con estos controles rigurosos:

  • [ ] Lógica Desacoplada: ¿Hay cero lógica de negocio en Procesos de Página o Acciones Dinámicas?
  • [ ] Variables de Vinculación (Bind Variables): ¿Estás usando variables de vinculación exclusivamente? Nada de concatenación de cadenas para valores.
  • [ ] Auditoría Basada en Contexto: ¿Tu Servicio de Datos usa sys_context para los campos created_by?
  • [ ] Errores Amigables para APEX: ¿Tu capa de lógica usa apex_error.add_error para el feedback en la UI?
  • [ ] Operaciones Masivas: ¿Los procesos por lotes usan FORALL para minimizar el cambio de contexto?

Conclusión: Arquitectura sobre sintaxis

La sintaxis cambia con las versiones; la arquitectura permanece. Al mover la
lógica fuera de APEX y hacia una Capa de Servicio estructurada en PL/SQL,
transformas tu aplicación en un activo de ingeniería profesional. Además de la
mantenibilidad, este enfoque es la única forma de habilitar CI/CD y
Pruebas Unitarias; los pipelines automatizados pueden probar paquetes
fácilmente, pero son ciegos a la lógica atrapada dentro del Page Designer de
APEX.

Recuerda: cada componente del Page Designer que evitas es una victoria para tu
"yo" del futuro.


📖 Leer más

Si te gustó este artículo, también te puede interesar:


Referencias


🚀 ¿Necesitas un Experto en APEX?

Ayudo a empresas a facilitar el desarrollo profesional de Oracle APEX y DevOps.
Si quieres construir mejores aplicaciones o automatizar tu pipeline,
hablemos.

☕ Agendar un Café
💼 Conectar en LinkedIn
🐦 Seguir en X

Top comments (0)