Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.


Info

Para utilizar APIs desplegadas en local, disponemos de esta guía: Conexión a las APIs locales

Tabla de contenidos

...


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ánel Portal de Servicios tenemos el archivo api.js, que define apiRequest, que será lo que utilicemos para hacer nuestras llamadas, definido así:

Bloque de código
languagejs
titleapiRequest
export const ENDPOINTapiRequest = 'https://enpointrest.um.es/consultaexpedientes/rest/v1.0/private';

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

Bloque de código
languagejs
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:

  • config: contiene la configuración que ha utilizado axios para realizar la llamada.
  • data: los datos que se reciben como respuesta. En el caso del ejemplo sería el expediente.
  • headers: headers que contiene la respuesta.
  • request: es la petición que ha generado la respuesta.
  • status: código HTTP de la respuesta del servidor.
  • statusText: mensaje de estado de la respuesta del servidor.

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:

Bloque de código
languagejs
...
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):

Image Removed

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

({
  method = 'GET',
  data = {},
  url,
  root = false,
  responseType = 'json',
}) => axios({
  url: `${root ? '' : environmentURL || ''}${url}`,
  method,
  data,
  responseType,
}).catch(
  (error) => {
    throw error;
  },
);

Como vemos, por defecto hace un GET, y se espera un json como respuesta.

Para definir nuestras llamadas a las apis, nos crearemos un único archivo en cada servicio, llamado servicio.api.js, siendo servicio algo indicativo de nuestro servicio. Por ejemploEl 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:

Bloque de código
languagejs
titlehistorico.api.js
importpromise.then(
	function(result) { /*apiRequest Código} en respuesta a un resultado exitoso */ },
	function(error) { /* Código en respuesta a un error */ }
);

O de forma abreviada:

Bloque de código
languagejs
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:

Bloque de código
languagejs
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:

Bloque de código
languagejs
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:

Bloque de código
languagejs
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:

Bloque de código
languagejs
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:

from '@/api';

const moduleBaseApiURL = '/historico/guiadocente/api/';
const apiVersion = 'v1';

const endpoints = {
  pdf: `${moduleBaseApiURL}public/2/getpdf/`,
  search: `${moduleBaseApiURL}public/${apiVersion}/search/`,
  select: `${moduleBaseApiURL}public/${apiVersion}/select/`,
};

const syllabusApi = {
  endpoints: () => endpoints,
  searchSyllabus: (text) => {
    const url = `${endpoints.search}${text}`;
    return apiRequest({ url });
  },
  select: (type, id) => {
    const url = `${endpoints.select}${type}/${id}`;
    return apiRequest({ url });
  },
};

export default syllabusApi;

Debemos seguir siempre esta estructura:

  • Importar apiRequest.
  • moduleBaseApiURL: ruta base del backend.
  • apiVersion: versión de la api.
  • endpints: objeto con todos los endpoints que se utilizarán, construyéndolos como vemos en el ejemplo.
  • xxxapi: cada una de las llamadas, incluyendo endpoints al principio.
  • export default xxxapi
  • resolve(value) - si la tarea ha finalizado con éxito, devolviendo value.
  • reject(error) - si se ha producido un error, devolviendo el objeto error.