# Integración REST API en Oracle APEX

[🇺🇸 Read in English](https://insightsapex.vinnyum.tech/rest-api-integration-oracle-apex)

## 1\. Introducción: El Mundo "API-First"

Las aplicaciones modernas rara vez viven aisladas. Intercambian datos con CRMs, ERPs, pasarelas de pago y microservicios internos. Para los desarrolladores de Oracle APEX, dominar la **integración REST API** ya no es opcional: es una habilidad profesional fundamental.

En esta edición de *APEX Insights*, vamos más allá del típico "Hola Mundo". Exploraremos cómo **arquitectar integraciones mantenibles** que separen la lógica de la configuración, un principio clave que discutimos en [Dominando la Modularidad](https://insightsapex.vinnyum.tech/dominando-la-modularidad).

**Lo que aprenderás:**

*   **Declarativo vs. Código:** Cuándo usar Fuentes de Datos REST (REST Data Sources) vs. PL/SQL.
    
*   **Sincronización:** Cómo cachear datos externos automáticamente para mejorar el rendimiento.
    
*   **El Patrón Moderno:** Usar `APEX_EXEC` para desacoplar las URLs de tu código.
    
*   **Enviando Datos:** Generación de payloads JSON complejos para peticiones POST.
    

* * *

### ⚠️ Prerrequisito: Listas de Control de Acceso (ACLs)

Antes de que tu base de datos pueda hablar con el mundo exterior, debes darle permiso. Si estás en una base de datos On-Premises (o OCI DB System), es probable que falles con `ORA-24247: network access denied` a menos que configures una ACL.

```sql
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host       => 'api.stripe.com',
    lower_port => 443,
    upper_port => 443,
    ace        => xs$ace_type(privilege_list => xs$name_list('connect'),
                              principal_name => 'APEX_230200', -- Tu Dueño de Esquema
                              principal_type => xs_acl.ptype_db));
END;
/
```

*Nota: Autonomous Database maneja esto automáticamente para la mayoría de endpoints HTTPS públicos.*

* * *

## 2\. El Paisaje de Integración en Oracle APEX

Oracle APEX ofrece dos enfoques principales para trabajar con APIs REST. Elegir el correcto es la primera decisión arquitectónica que tomas.

### 2.1 Fuentes de Datos REST (Declarativo)

Las Fuentes de Datos REST (o *REST Data Sources*) tratan a las APIs como tablas de base de datos estándar.

**Ideal para:**

*   Reportes (Interactive Reports/Grids).
    
*   Dashboards y Gráficos.
    
*   Integraciones de mucha lectura.
    

### 2.2 Integración Programática (`APEX_EXEC` y `APEX_WEB_SERVICE`)

Para flujos transaccionales (ej. "Crear Pedido", "Procesar Pago"), necesitas control total en PL/SQL.

> **Regla Profesional:** Empieza declarativo. Si se requiere lógica personalizada, usa PL/SQL pero **mantén la configuración declarativa** (ver Sección 4).

* * *

## 3\. Poder Declarativo: Fuentes de Datos REST y Sincronización

En **Componentes Compartidos → Fuentes de Datos REST**, defines el Endpoint, la Autenticación (vía Credenciales Web) y el Perfil de Datos.

### 3.1 La "Feature Estrella": Sincronización

Consultar una API externa lenta cada vez que un usuario carga una página es una mala práctica. La **Sincronización** resuelve esto nativamente.

```mermaid
graph LR
    API[API Externa] -- Lento (2s) --> Sync[Tabla Local<br/>SYNC_DATA]
    Sync -- Rápido (Milisegundos) --> APEX[Reportes APEX]
    Scheduler[Sync Automático] -.-> API
```

1.  En tu Fuente de Datos REST, ve a **Gestionar Sincronización**.
    
2.  **Tabla Destino:** APEX crea una tabla local (ej. `SYNC_STRIPE_CHARGES`) para guardar los datos.
    
3.  **Programación:** Configúralo para correr cada hora, día o bajo demanda.
    

Ahora, tus componentes APEX consultan la **Tabla Local** (milisegundos) en lugar de la **API Externa** (segundos). Los datos se mantienen frescos automáticamente en segundo plano.

* * *

## 4\. El Patrón Moderno: `APEX_EXEC` sobre `APEX_WEB_SERVICE`

Un error común es "hardcodear" URLs en PL/SQL usando `APEX_WEB_SERVICE`.

**El Anti-Patrón (Hardcoded):**

```plsql
l_clob := apex_web_service.make_rest_request(
    p_url => 'https://api.stripe.com/v1/charges', ... -- ❌ URL Hardcodeada
);
```

**El Patrón Profesional (**`APEX_EXEC`**):** Define el módulo en "Fuentes de Datos REST" (configuración declarativa) y llámalo desde PL/SQL.

```plsql
DECLARE
    l_params apex_exec.t_parameters;
BEGIN
    apex_exec.add_parameter(l_params, 'customer_id', 101);

    apex_exec.execute_rest_source(
        p_static_id => 'STRIPE_CHARGES', -- ✅ Refiere al Componente Compartido
        p_operation => 'POST',
        p_parameters => l_params
    );
END;
```

**¿Por qué?** Si la URL de la API cambia, actualizas los *Componentes Compartidos*, no tu código de paquete. Esto separa la "Configuración" de la "Lógica".

* * *

## 5\. Enviando Datos: Manejo de JSON y Peticiones POST

La integración no es solo leer; se trata de empujar datos.

### 5.1 Generando el Payload y Manejo Robusto de Errores

No concatenes cadenas para construir JSON. Usa `APEX_JSON`. Y críticamente, **parsea las respuestas de error**.

```plsql
DECLARE
    l_response CLOB;
    l_error_msg VARCHAR2(4000);
BEGIN
    -- 1. Construir Payload JSON
    apex_json.initialize_clob_output;
    apex_json.open_object;
        apex_json.write('customer', 'Acme Corp');
        apex_json.write('amount', 1250.50);
        apex_json.open_array('items');
            apex_json.open_object;
            apex_json.write('sku', 'PRO-100');
            apex_json.close_object;
        apex_json.close_array;
    apex_json.close_object;
    
    -- 2. Enviar Petición
    apex_web_service.g_request_headers(1).name  := 'Content-Type';
    apex_web_service.g_request_headers(1).value := 'application/json';

    l_response := apex_web_service.make_rest_request(
        p_url                  => 'https://api.example.com/v1/orders',
        p_http_method          => 'POST',
        p_body                 => apex_json.get_clob_output,
        p_credential_static_id => 'MY_API_KEY'
    );
    
    apex_json.free_output;

    -- 3. Validar Éxito y Parsear Detalles de Error
    IF apex_web_service.g_status_code NOT IN (200, 201) THEN
        -- Intentar extraer error legible del JSON de respuesta
        BEGIN
            apex_json.parse(l_response);
            -- El formato varía según la API
            l_error_msg := apex_json.get_varchar2('error.message');
        EXCEPTION WHEN OTHERS THEN
            l_error_msg := 'Error de API Desconocido';
        END;
        
        raise_application_error(-20001, 
            'Integración Falló (' || apex_web_service.g_status_code || '): ' ||
            l_error_msg
        );
    END IF;
END;
```

* * *

## 6\. Tip Pro: Depurando Integraciones (Debugging)

Cuando una integración falla, "Adivinar" no es una estrategia. Oracle APEX registra cada petición saliente cuando el Debug está habilitado.

1.  Habilita **Debug Level 9 (Trace)** para tu página o sesión.
    
2.  Ejecuta la petición.
    
3.  Ve al Debug Log (`View Debug`).
    
4.  Filtra por `APEX_WEB_SERVICE`.
    

Verás la URL **exacta**, Headers y Body de la Petición enviados, así como la Respuesta cruda. Esto es indispensable para solucionar errores de Auth (401) o Bad Requests (400).

* * *

## 7\. Seguridad: La Regla de "No Hardcoding"

**Nunca** guardes API Keys en constantes de paquetes.

1.  **Credenciales Web:** Guarda secretos en *Utilidades del Espacio de Trabajo → Credenciales Web*.
    
2.  **Conciencia de Entorno:** APEX maneja URLs y Keys de Dev/Prod automáticamente vía cadenas de sustitución en Componentes Compartidos.
    

* * *

## Conclusión

La integración REST en APEX es poderosa cuando sigues la arquitectura: **Configuración declarativa primero, lógica PL/SQL segundo.**

**Checklist:**

*   \[ \] Usa **Sincronización** para datos externos de mucha lectura.
    
*   \[ \] Usa **APEX\_EXEC** para desacoplar PL/SQL de las URLs.
    
*   \[ \] Usa **Credenciales Web** para toda la seguridad.
    
*   \[ \] Maneja errores **4xx/5xx** parseando el payload de respuesta.
    

* * *

## 📘 Referencias

1.  **Documentación Oracle APEX: Fuentes de Datos REST**[https://docs.oracle.com/en/database/oracle/apex/24.2/htmdb/managing-REST-data-sources.html](https://docs.oracle.com/en/database/oracle/apex/24.2/htmdb/managing-REST-data-sources.html)
    
2.  **Referencia de API APEX\_WEB\_SERVICE**[docs.oracle.com/en/database/oracle/apex/24.2/aeapi/APEX\_WEB\_SERVICE.html](https://docs.oracle.com/en/database/oracle/apex/24.2/aeapi/APEX_WEB_SERVICE.html)
    
3.  **Parseando JSON en APEX**[docs.oracle.com/en/database/oracle/apex/24.2/aeapi/APEX\_JSON.html](https://docs.oracle.com/en/database/oracle/apex/24.2/aeapi/APEX_JSON.html)
    

* * *

### 💖 Apoya mi trabajo

Si encuentras útil este artículo, ¡considera apoyarme!

[**GitHub Sponsors**](https://github.com/sponsors/aguilavajz) | [**Buy Me a Coffee**](https://www.buymeacoffee.com/vinnyum)

Tu apoyo me ayuda a seguir creando demos open-source y contenido de calidad para la comunidad Oracle APEX. 🚀
