Usando Axios

Seguimos con las recetas breves de temas muy concretos, que si bien soy consciente no son especialmente complejas, si que sirven, por lo menos para mi, como recordartorio de algunas configuraciones que está bien tener siempre frescas.

Hoy vamos a usar Axios para acceder a una API y mostrar algunos datos en pantalla y consola.

Axios es fundamentalmente una libreria JS que nos permite hacer peticiones muy estructuradas de datos y que cuenta, entre otras ventajas en que las respuestas ya vienen serializadas en un JSON, con lo que no es necesario hacer ningún tipo de conversión una vez hemos hecho la petición.

Podemos usar Axios en Node.js, como parte de un proyecto Vue.js por ejemplo o directamente trayendo la librería a través de su CDN, que es precisamente lo que vamos a ver en este ejemplo.

Planificando el entorno

Para poder ver el ejemplo, necesitamos en primer lugar el acceso a una API. En esta ocasión, en vez de recurrir a algunos de los casos que anteriormente hemos usado, vamos a acceder a unos datos de prueba que nos provee {JSON} Placeholder, un sitio web que deja a nuestra disposición diferentes API’s de prueba para hacer testeos.

En concreto, para este ejemplo, vamos a usar un endpoint que nos devuelve un listado de usuarios con ID, nombre y email, nada más

Para el ejemplo, he montado una pequeña aplicación que simplemente muestra los datos de la API y dispone de un pequeño formulario muy simple, para cargar nuevos datos.

Como siempre, me gusta mantener el orden todo lo posible en los proyectos, y aunque se trate de un caso de prueba muy simple, he oganizado las carpetas y archivos para que queden bien separadas las vistas y la lógica:

  • En la carpeta js, figuran los ficheros de conexión a la API, las llamadas GET y POST y el control de las acciones del formulario
  • En la carpeta templates, figuran las vistas de header, footer y contenido principal.
  • En la raíz, el fichero index.php se encarga de mostrar y ejecutar todos los procesos.

El código al detalle

En primer lugar, montamos un fichero llamado axios_instance.js, que contendrá la llamada al endpoint y si fuera necesario, otras configuraciones como el usuario, password, etc.

// axios_instance.js

// Creamos una instancia de axios
const axiosInstance = axios.create({
    baseURL: 'https://jsonplaceholder.typicode.com', // EndPoint de pruebas
    timeout: 5000, // Tiempo máximo de espera para la petición
});

El fichero axios_acciones.js, incluirá las acciones que podemos llevar a cabo en nuestro ejemplo. En este caso, solamente se han implementado una llamada GET y POST para la API, un interceptor y una función sencilla js para mostrar un mensaje de OK, si los datos se han cargado correctamente.

// js/axios_acciones.js

// Función para realizar la petición a la API
async function LlamadaGET() {
    try {
        const response = await axiosInstance.get('/users');
        // Mostramos los datos por consola
        console.log(response.data);

        // Limpiar contenido actual de la tabla
        $('#outputTableBody').empty();

        // Construir filas y celdas en la tabla
        response.data.forEach(user => {
            const row = `<tr>
                <td>${user.id}</td>
                <td>${user.name}</td>
                <td>${user.email}</td>
                <!-- Agrega más celdas según la estructura de tus datos -->
            </tr>`;
            $('#outputTableBody').append(row);
        });
    } catch (error) {
        console.error(error);
    }
}

// Llamar a la función al cargar el documento
LlamadaGET();

// Función LlamadaPOST
async function LlamadaPOST(nuevoUsuario) {
    try {
        // En este ejemplo, `nuevoUsuario` es un objeto que contiene los datos del nuevo usuario
        const response = await axiosInstance.post('/users', nuevoUsuario);

        // Mostrar la respuesta de la petición POST en la consola
        console.log(response.data);

        // Mostrar una alerta de éxito
        mostrarAlertaExito();

        // Si la inserción fue exitosa, puedes volver a cargar la tabla actualizando los datos
        await LlamadaGET();
    } catch (error) {
        console.error(error);
    }
}
// js/axios_acciones.js

// .... CODIGO ANTERIOR ....

// MENSAJE DE CARGA OK
function mostrarAlertaExito() {
    const alertaExito = $('<div>').addClass('alert alert-success').text('¡Registro cargado correctamente!');

    // Limpiar el contenido actual del elemento antes de agregar la nueva alerta
    $('#alertaExito').empty();

    // Añadir el elemento de alerta al elemento con el identificador 'alertaExito'
    $('#alertaExito').append(alertaExito);

    // Desaparecer la alerta después de un tiempo 
    setTimeout(() => {
        alertaExito.remove();
    }, 3000); 
}

Un concepto interesante, aunque un poco abstracto, es el de interceptor. En la documentación de Axios, indican que los interceptores son interrupciones o respuestas personalizadas a las peticiones, que sirven para introducir modificaciones al vuelo en estas peticiones o manejar las repuestas, antes de que lleguen al usuario.

// js/axios_acciones.js

// .... CODIGO ANTERIOR ....

// Configurar un interceptor para mostrar mensajes en la consola
axiosInstance.interceptors.request.use(request => {
    console.log('Este es el interceptor', request);
    return request;
});

axiosInstance.interceptors.response.use(response => {
    console.log('Respuesta del interceptor:', response);
    return response;
}, error => {
    console.error('Respuesta de error del interceptor:', error);
    return Promise.reject(error);
});

Otro fichero implicado en la gestión de la aplicación es acciones_formulario.js, que no sirve más que para recoger los datos del formulario de nuevo usuario para crear con ellos objeto que pasaremos a la llamada a la función POST de la API.

// js/acciones_formulario.js

// Captura el evento de envío del formulario usando jQuery
$('#userForm').submit(function (event) {
    event.preventDefault(); // Evita el envío tradicional del formulario

    // Obtiene los valores del formulario
    const nombre = $('#nombre').val();
    const email = $('#email').val();

    // Crea un objeto con los datos del nuevo usuario
    const nuevoUsuario = {
        name: nombre,
        email: email
       
    };

    // Realiza la llamada POST para agregar un nuevo usuario
    LlamadaPOST(nuevoUsuario);

});

Ahora para la parte visual, se ha montado un pequeño código que incluye Bootstrap para dar una imagen más agradable a la aplicación. En el fichero header.php, es importante cargar adecuadamente todas las referencias a los ficheros js vistos antes.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Axios y PHP</title>

    <!-- Incluir Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    
    <!-- Incluir jQuery -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

    <!-- Incluir Axios -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    
    <!-- Incluir el archivo axios_instance.js -->
    <script src="js/axios_instance.js"></script>
    
    <!-- Incluir el archivo axios_acciones.js -->
    <script src="js/axios_acciones.js"></script>

</head>
<body>

El contenedor principal, incluye el formulario de carga y la tabla para visualizar los datos:

<div class="container mt-5">
    <h1>Ejemplo con Axios y PHP</h1>
         <!-- Formulario para agregar nuevo usuario en una sola línea -->
        <div class="bg-secondary" style="padding: 10px;">
            <form id="userForm" class="form-inline">
                <div class="form-group mx-sm-3 mb-2">
                    <label for="nombre" class="sr-only">Nombre:</label>
                    <input type="text" class="form-control" id="nombre" name="nombre" placeholder="Nombre" required>
                </div>
                <div class="form-group mx-sm-3 mb-2">
                    <label for="email" class="sr-only">Email:</label>
                    <input type="text" class="form-control" id="email" name="email" placeholder="Email" required>
                </div>
                <!-- Agrega más campos según la estructura de tus datos -->
                <button type="submit" class="btn btn-warning mb-2">Agregar Usuario</button>
            </form>
        </div>

        <!-- AQUI MOSTRAMOS LOS MENSAJES SI VA OK LA CARGA DE DATOS -->
        <div id="alertaExito" style="padding: 10px;"></div>

    <!-- Agregar una tabla con un identificador único para mostrar la salida de la API -->
    <table class="table" id="outputTable">
        <thead>
            <tr>
                <th>ID</th>
                <th>Nombre</th>
                <th>Email</th>
                <!-- Agrega más encabezados según la estructura de tus datos -->
            </tr>
        </thead>
        <tbody id="outputTableBody"></tbody>
    </table>
</div>

Y el footer, trae la llamada al fichero de acciones del formulario y el cierre de todo el código:

<!-- Incluir Bootstrap JS (Requiere Popper.js y jQuery) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"  crossorigin="anonymous"></script>

<!-- Incluir el archivo acciones_formulario.js -->
<script src="js/acciones_formulario.js"></script>

</body>
</html>

Finalmente, el fichero principal index.php, nos sirve para cargar todo:

<?php 
// header.php
include('templates/header.php');

// contenido principal content.php
include('templates/content.php');

// footer.php
include('templates/footer.php');

En marcha

Ahora llega el momento de ver en marcha la aplicación. En primer lugar, cuando arrancamos la página podemos ver que se cargan una serie de datos, que se vuelcan en este caso, tanto en pantalla como en la consola:

En pantalla, al usuario y para simplificar, solamente mostramos una fracción de los datos: Id, nombre y email

Con lo cual podemos comprobar que la llamada GET a la API, funciona como se espera.

La carga de datos, se va a realizar mediante el formulario que aparece en la parte superior, donde se recoge el nombre y el email del futuro usuario. Al lanzar la petición, se activan los interceptores que hemos diseñado, muestran los mensajes correspondientes y se genera el nuevo usuario.

Hay que tener clara una cosa, al ser una api de pruebas, la llamada GET solo está preparada para enviar los 10 primeros registros, con lo cual, aunque carguemos correctamente un nuevo usuario, no se reflejará en el listado en pantalla, pero la API nos responde que la carga ha sido OK.

Como vemos, la llamada a la función POST ha disparado el interceptor, que nos devuelve un mensaje en consola y seguidamente hace la inserción, con respuesta 201, indicando que todo ha ido OK

Después de la carga, vuelve a dispararse el interceptor a la hora de listar de nuevo los datos, mostrar un mensaje en consola y el status 200, indicando que la recogida de los datos ha sido correcta

Pues eso es todo.

Hasta aquí hemos visto otra forma de acceder a los datos de una API, de forma muy sencilla y usando librerias JS modernas, que nos permiten un control muy exhaustivo de la forma en que recogemos esa información y como la mostramos.

Como siempre, el código de este ejemplo, está disponible en mi cuenta de GitHub para que puedas estudiarlo y hacer las modificaciones que necesites para adpatarlo a tus necesidades.

Publicada el
Categorizado como Desarollo Etiquetado como ,

Por Jose Manuel Sanz Prieto

Desarrollador web. En este blog hablo de fotografía, programación con Django, Python, PHP y privacidad.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *