Llamadas a servicios REST

Para hacer las llamadas al backend utilizaremos el paquete Axios. En nuestro proyecto tendremos una carpeta services con los archivos Javascript que contengan los servicios. Un ejemplo podría ser el siguiente. Nos definimos un archivo endpoints.js para tener las URLs a las que se llamarán:

export const ENDPOINT = 'https://enpointrest.um.es/consultaexpedientes/rest/v1.0/private';

Y el archivo de nuestro servicio, por ejemplo ServicioExpedientes.js:

import axios from "axios";
import { ENDPOINT } from "./endpoints";
 
export default class ServicioExpedientes {
  getExpediente(dni) { 
    return axios.get("/expediente?dni=" + dni);
  }
}

El objeto que se obtiene como respuesta tiene los siguientes campos:

Con esto podemos comprobar que la la petición y la respuesta han sido correctas, y obtener los datos solicitados.

Posteriormente, en nuestros componentes, tendremos que definirnos nuestro servicio e inicializarlo. Al hacer las peticiones, debemos tener en cuenta que las peticiones se realizan de forma asíncrona, es decir, se lanzará la petición y seguirá ejecutando el código aunque no se haya recibido la respuesta. El código que deseamos que se ejecute como reacción a la respuesta tendrá que ir en .then(...), de la siguiente manera:

...
export default {
  data() {
    ...
  },
  servicioExpedientes: null,
  created() {
    this.servicioExpedientes = new ServicioExpedientes();
  },
  methods: {
    método() {
      this.servicioExpedientes(this.dni).then((response) => {
		if(response.status == 200) {
        	this.docUniversitarrio = response.data;
		}
      })
    }
  }
}

El objeto que obtenemos al hacer las llamadas a la API es de tipo Promise, que pasamos a ver cómo funciona.

Promesas (Promise) en JavaScript

En el desarrollo de aplicaciones FundewebJS vamos a tener que lidiar con el tipo de dato Promise de JavaScript, sobre todo en las llamadas a APIs REST. Los objetos Promise se inicializan, ejecutan una tarea y se resuelven (o se rechazan):

Este proceso se ejecuta de forma asíncrona, es decir, una vez se crea el objeto Promise, el código seguirá ejecutándose independientemente de que se la tarea de la Promise haya finalizado o no. Esto, en llamadas a servicios REST se traduce en que enviamos la petición al servidor y, antes de haber obtenido una respuesta, se sigue ejecutando el código.

Consumir objetos Promise

En el caso mencionado, actuaremos como consumidores de un objeto Promise que nos dará la llamada a la API REST, por lo tanto lo que haremos será reaccionar al resultado obtenido, estableciendo las funciones con .then, .catch y .finally, que nos resultará familiar si hemos desarrollado con otros lenguajes de progamación, como Java.

.then

El método más importante es .then, donde especificaremos el código a ejecutar en el momento en el que la promesa se resuelva o se rechace. Tendrá la siguiente sintaxis:

promise.then(
	function(result) { /* Código en respuesta a un resultado exitoso */ },
	function(error) { /* Código en respuesta a un error */ }
);

O de forma abreviada:

promise.then(
	(result) => { /* Código en respuesta a un resultado exitoso */ },
	(error) => { /* Código en respuesta a un error */ }
);

El primer argumento define la función que se ejecutará en el momento en el que se resuelva la promesa, y el segundo argumento la función que se ejecutará si se devuelve un error. Si solo estamos interesados en reaccionar a una respuesta exitosa, podemos indicar únicamente el primer argumento.

.catch

Si estamos interesados únicamente en reaccionar los errores, podemos utilizar .then(null, funcion), o podemos utilizar .catch(funcion), que haría exactamente lo mismo:

promise.catch((error) => { /* Código en respuesta a un error */ });

.finally

Por último, la función que indiquemos en el .finally se ejecutará después de que la promesa haya dado un valor, ya sea un valor correcto o un error, y su sintaxis sería la siguiente:

promise.finally(() => { /* Código */ });

Una prticularidad del .finally es que no tiene por qué ser el último trozo de código que se ejecute. Todos estos métodos se ejecutan una vez haya finalizado la promesa, la diferencia es que .finally no recibe ningún argumento; no sabe si la finalización ha sido exitosa o no. Poniéndolo antes de .then o .catch, su código se ejecutará antes:

promise.finally(() => alert("Promesa lista").then(result => alert(result));
promise.finally(() => alert("Promesa lista").catch(err => alert(err));

Crear objetos Promise

Aunque en nuestro caso será menos necesario, también es importante conocer cómo se crean los objetos Promise. La sintaxis del constructor de un objeto promise sería la siguiente:

let promise = new Promise(function(resolve, reject) {
	// executor (el código que ejecutará la Promise)
});

La función que se le pasa al new Promise se llama executor, que se ejecuta automáticamente cuando se crea la Promise, y producirá el resultado. Esta función devuelve un resultado llamando a uno de estos dos callbacks: