Cómo conectarte a una API con JavaScript

Javascript

En este tutorial vamos a explicar qué es una API y cómo te puedes conectar a una API con JavaScript. Para ello crearemos una aplicación de ejemplo que usaremos para conectarnos a una API Rest, de la cual obtendremos datos de forma asíncrona.

Esto es algo que como desarrollador tendrás que hacer en tu día a día, ya que las aplicaciones cliente servidor típicas en las que las vistas se generan en el servidor están dando paso a aplicaciones que se ejecutan en el navegador del usuario. Estas aplicaciones suelen obtiener los datos desde una o varias APIs asíncronamente.

A continuación puedes ver tanto el código del proyecto como la aplicación que vamos a crear:

Introducción

Vamos a crear una sencilla aplicación usando JavaScript, HTML y CSS. Mediante JavaScript, obtendremos los datos de esta API y mostraremos los resultados por pantalla. Se trata de un ejemplo sencillo que pretende ser útil para que los que nunca hayan usado una API, por lo que no es el objetivo de este tutorial el de usar todos los elementos de la especificación REST, que define cómo se deben crear, obtener, actualizar y borrar los datos mediante una API. En este tutorial nos centraremos únicamente en la obtención de datos mediante peticiones GET.

Antes de continuar con este tutorial, se recomienda que tengas ciertos conocimientos básicos de JavaScript, HTML y CSS. Si no los tienes, puedes consultar las siguientes guías antes de continuar:

Primero veremos qué es una API, luego cómo obtener los datos de la misma mediante una petición HTTP GET y finalmente cómo mostrar los datos obtenidos en el documento HTML dinámicamente mediante JavaScript.

Qué es una API

El término API deriva de Application Program Interface y se define como la implementación de una metodología de comunicación entre varios componentes o sistemas. Una API permite que un sistema, una aplicación o un componente intercambie información con otros.

En este tutorial usaremos una API web, que permite a un cliente o a un servidor intercambiar datos con otro servidor. En este caso, el cliente será un navegador web como el que seguramente estés usando ahora, y el servidor será el sistema en el que está localizada la API a la que nos conectaremos mediante peticiones HTTP. Mediante dichas peticiones nos conectaremos a una URL o endpoint de la API, obteniendo datos en formato JSON de vuelta.

La mayor parte de las APIs web implementan la arquitectura CRUD, que permite crear registros, obtenerlos, actualizarlos y eliminarlos. Una API que implementa las operaciones CRUD también suele recibir el nombre de API REST si soporta los siguientes métodos HTTP, correspondiéndose con sus respectivos verbos CRUD:

Acción CRUD Método HTTP Descripción
Creación POST Creación de un registro
Lectura GET Obtención de un registro
Actualización PUT o PATCH Actualización de un registro
Borrado DELETE Borrado de un registro
Las APIs REST implementan usa serie de estándares que dan forma a la arquitectura REST, que es una de las más utilizadas a día de hoy cuando desarrollas aplicaciones web o aplicaciones móviles. No necesitas entender estos conceptos para seguir este tutorial, pero en caso de que quieras saber más cosas acerca de esta arquitectura, puedes echarle un ojo al siguiente tutorial, en el que explico qué es y cómo se implementa una API REST.

Acerca de la API

Vamos a obtener datos desde la API definida en este enlace. En concreto obtendremos los títulos y las descripciones de varias películas y mostraremos los datos por pantalla.

Si consultas la documentación de la API que vamos a utilizar, podrás comprobar que ha sido creada con el fines de aprendizaje, por lo que no es una API compleja. Podrás conectarte a ella usando cualquier lenguaje de programación, ya que en general, una API se limita a implementar una arquitectura mediante un protocolo, siendo compatible con cualquier lenguaje de programación capaz de crear las peticiones soportadas.

La API dispone de un endpoint que nos permite obtener una lista de películas si realizamos una petición GET a la URL /films. De hecho, si accedes a la URL https://ghibliapi.herokuapp.com/films directamente, podrás ver el código JSON que incluye la lista de películas a obtener.

Configuración inicial

Antes de obtener datos de la API, vamos a crear un documento HTML y otro archivo JavaScript. Comenzaremos creando una archivo llamado index.html en una carpeta vacía. Para ello podemos comenzar por incluir el código de esta plantilla básica HTML. Vamos a crear también en el mismo directorio el archivo scripts.js, en donde incluiremos el código JavaScript del proyecto.

Además de estos dos archivos, también vamos a incluir el framework CSS Bootstrap, ya que no es el objetivo de este tutorial el de aprender CSS. Este framework sencillamente nos proporciona una serie de clases CSS predefinidas, ahorrándonos bastante trabajo. Si nunca has usado Bootstrap, puedes consultar el tutorial de introducción a Bootstrap, aunque no es imprescindible para seguir este tutorial.

Finalmente, también vamos a incluir una fuente desde Google Fonts, aunque puedes usar la que más te guste:

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Tutorial API JavaScript</title>

    <script defer src="scripts.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <h1 class="text-center pt-5 pb-4">Lista de películas</h1>
      <hr>
      <div id="contenedor">
        <!-- Lista de películas -->
      </div>
    </div>
  </body>
</html>

Tal y como ves, hemos cargado el archivo JavaScript scripts.js en la sección head del archivo HTML usando defer, ya que es el método más eficiente de cargar scripts en JavaScript. En el interior del body, únicamente hemos agregado un encabezado h1 y el div en el que incluiremos los elementos obtenidos.

Realizando la petición

Ahora que ya hemos realizado la configuración inicial, vamos a editar el archivo scripts.js, en donde agregaremos el código necesario para obtener datos de la API. Vamos a realizar una petición usando un objeto XMLHttpRequest. Podríamos usar la API Fetch de JavaScript, que es un wrapper que simplifica estas peticiones o alguna librería como Axios. Sin embargo, con fines de aprendizaje, usaremos peticiones XMLHttpRequest.

En cualquier caso, tanto la API Fetch como la librería Axios se basan en peticiones XMLHttpRequest, que son un método que nos permite obtener archivos mediante peticiones HTTP.

Vamos a comenzar creando una constante llamada request a la que asignaremos un nuevo objeto XMLHttpRequest que crearemos invocando a su constructor. Luego usaremos el método open del objeto, que soporta tres argumentos, siendo el primero de ellos el verbo que define el tipo de petición a realizar, que en este caso será el parámetro GET. El segundo argumento es la URL a la que vamos a realizar la petición, que en nuestro caso es la URL https://ghibliapi.herokuapp.com/films. El tercer parámetro sirve para definir si la petición será o no asíncrona, usando el valor true, que es además su valor por defecto, por lo que podríamos obviarlo:

const request = new XMLHttpRequest();
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true);

Ahora vamos a asignar una función a la propiedad onload del objeto XMLHttpRequest, que nos permite definir la acción a ejecutar cuando se obtengan los datos de vuelta. Le asignaremos una función que por ahora estará vacía:

request.onload = function () {
  // Acciones a realizar
}

Finalmente enviamos la petición usando el método send del objeto XMLHttpRequest:

request.send();

Gestión de la respuesta

Recibiremos una respuesta a la petición HTTP en la función que hemos asignado a la propiedad onload. La respuesta estará en formato JSON, por lo que debemos convertir el código JSON en un objeto JavaScript. Para realizar esta conversión usaremos el método JSON.parse, que recibirá la respuesta como parámetro, asignado el resultado a una constante a la que llamaremos data:

request.onload = function () {
  const data = JSON.parse(this.response);
  data.forEach((pelicula) => {
    console.log(pelicula.title);
  });
}

Hemos recorrido la lista de películas obtenida mediante un bucle forEach, mostrando por la consola el título de cada una de las películas obtenidas. Si accedes a la consola del navegador, deberías poder ver cómo se muestran las películas.

Sin embargo, deberíamos gestionar el código de la petición de algún modo, comprobando así si ha ocurrido algún error, algo que podría darse si la API no está disponible, si su servidor está caído o si usamos el endpoint incorrecto. Toda petición HTTP devolverá uno de estos códigos de estado HTTP. Si el código devuelto es el 200, la respuesta será válida, pero otros códigos como el 400 o el 404 se usan para indicar que ha ocurrido algún error.

Vamos a comprobar si el código devuelto está entre los valores 200 y 300. Si no lo está, en lugar de recorrer las películas, que no estarán presentes, mostraremos un mensaje de error por la consola:

request.onload = function () {
  if (request.status >= 200 && request.status < 400) {
    const data = JSON.parse(this.response);
    data.forEach((pelicula) => {
      console.log(pelicula.title);
    });
  } else {
    console.log('Ha ocurrido un error conc ódigo ' + request.status);
  }
}

Sí, seguramente estés pensando que podríamos haber usado una sentencia try/catch, pero cuando usas directamente un objeto XMLHttpRequest, no saltará un error en caso de que se obtenga una respuesta inválida, como sí ocurre cuando usamos la API Fetch.

Este sería el código completo del archivo scripts.js con lo que hemos hecho hasta ahora:

const request = new XMLHttpRequest();
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true);

request.onload = function () {
  if (request.status >= 200 && request.status < 400) {
    const data = JSON.parse(this.response);
    data.forEach((pelicula) => {
      console.log(pelicula.title);
      console.log(pelicula.descripcion);
    });
  } else {
    console.log('Ha ocurrido un error conc ódigo ' + request.status);
  }
}

request.send();

Lo que haremos a continuación, en lugar de mostrar los resultados por la consola, será inyectar los contenidos obtenidos en el código HTML de la página, modificando el DOM de la página.

Mostrando los datos obtenidos

Para mostrar los resultados obtenidos tendremos que trabajar con el DOM, que es una API disponible en todos los navegadores que permite interactuar con el código HTML mediante JavaScript. Inyectaremos una serie de tarjetas con información acerca de las películas obtenidas, incluyendo su título y su descripción.

Si revisas el código HTML de la aplicación, podrás comprobare que hemos agregado un div cuyo atributo id es contenedor. Para obtener este elemento podemos usar el método document.getElementById, que nos permitirá obtener un elemento del DOM pasándole su id como parámetro.

const contenedor = document.getElementById('contenedor');

Vamos a asignarle la clase card-group al div contenedor, que es una clase de Bootstrap que permite organizar los elementos de su interior en tarjetas. para ello usaremos el método setAttribute, aplicable a los elementos obtenidos del DOM. Además también estableceremos un margen superior mediante la clase pt-4:

contenedor.setAttribute('class', 'card-group, pt-4');

Por ahora, este es el código de la función asignada al objeto request.onload de la petición:

request.onload = function () {
  if (request.status >= 200 && request.status < 400) {
    
    const data = JSON.parse(this.response);
    const contenedor = document.getElementById('contenedor');
    contenedor.setAttribute('class', 'card-group, pt-4');
    
    data.forEach((pelicula) => {
      console.log(pelicula.title);
      console.log(pelicula.descripcion);
    });
  } else {
    console.log('Ha ocurrido un error con código ' + request.status);
  }
}

En lugar de mostrar los elementos por la consola, vamos a crear una tarjeta por cada elemento o película, mostrando el título y la descripción de cada una de ellas. Para crear un nuevo elementos usaremos el método document.createElement. Los elementos div que representan a cada tarjeta tendrán la clase card de Bootstrap asignada. En su interior crearemos a su vez dos elementos div, uno con la clase card-header y otro con la clase card-body, para la cabecera y el cuerpo de cada tarjeta respectivamente.

En el div de la cabecera crearemos una etiqueta h5 con el título de la película, mientras que en el div del cuerpo agregaremos otro div con clase card-text para la descripción de la película. A continuación puedes ver el código del bucle forEach:

data.forEach((pelicula) => {
      
  // Creamos una tarjeta
  const tarjeta = document.createElement('div');
  tarjeta.setAttribute('class', 'card');

  // Creamos el la cabecera y el cuerpo de la tarjeta
  const cabeceraTarjeta = document.createElement('div');
  cabeceraTarjeta.setAttribute('class', 'card-header');

  const cuerpoTarjeta = document.createElement('div');
  cuerpoTarjeta.setAttribute('class', 'card-body');

  // Creamos el encabezado y le asignamos el título de la película
  const titulo = document.createElement('h5');
  titulo.setAttribute('class', 'card-title');
  titulo.textContent = pelicula.title;

  // Creamos la párrafo y le asignamos la descripción de la película
  pelicula.descripcion = pelicula.description.substring(0, 250);

  const descripcion = document.createElement('p');
  descripcion.setAttribute('class', 'card-text');
  descripcion.textContent = `${ pelicula.descripcion }...`;

  // Agregamos la tarjeta
  contenedor.appendChild(tarjeta);

  // Agregamos la cabecera y el cuerpo a la tarjeta
  tarjeta.appendChild(cabeceraTarjeta);
  tarjeta.appendChild(cuerpoTarjeta);

  // Agregamos el título a la cabecera
  cabeceraTarjeta.appendChild(titulo);
      
  // Agregamos la descripción al cuerpo
  cuerpoTarjeta.appendChild(descripcion);
});

Tal y como ves, también hemos limitado la descripción de la película a 250 caracteres y hemos agregado puntos suspensivos al final.

Vamos a reemplazar también el error que se muestra por la consola cuando es devuelto un código de error por una notificación en HTML, para lo cual podemos usar un alert de Bootstrap:

const errorMessage = document.createElement('div');
errorMessage.setAttribute('class', 'alert alert-danger');
errorMessage.textContent = `Ha ocurrido un error con código ${request.status}`;

contenedor.appendChild(errorMessage);

Este sería el código completo del archivo scripts.js:

const request = new XMLHttpRequest();
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true);

request.onload = function () {
  if (request.status >= 200 && request.status < 400) {

    const data = JSON.parse(this.response);
    
    const contenedor = document.getElementById('contenedor');
    contenedor.setAttribute('class', 'card-columns');
    
    data.forEach((pelicula) => {
      
      // Creamos una tarjeta
      const tarjeta = document.createElement('div');
      tarjeta.setAttribute('class', 'card');

      // Creamos el la cabecera y el cuerpo de la tarjeta
      const cabeceraTarjeta = document.createElement('div');
      cabeceraTarjeta.setAttribute('class', 'card-header');

      const cuerpoTarjeta = document.createElement('div');
      cuerpoTarjeta.setAttribute('class', 'card-body');

      // Creamos el encabezado y le asignamos el título de la película
      const titulo = document.createElement('h5');
      titulo.setAttribute('class', 'card-title');
      titulo.textContent = pelicula.title;

      // Creamos la párrafo y le asignamos la descripción de la película
      pelicula.descripcion = pelicula.description.substring(0, 250);

      const descripcion = document.createElement('p');
      descripcion.setAttribute('class', 'card-text');
      descripcion.textContent = `${ pelicula.descripcion }...`;

      // Agregamos la tarjeta
      contenedor.appendChild(tarjeta);

      // Agregamos la cabecera y el cuerpo a la tarjeta
      tarjeta.appendChild(cabeceraTarjeta);
      tarjeta.appendChild(cuerpoTarjeta);

      // Agregamos el título a la cabecera
      cabeceraTarjeta.appendChild(titulo);
      
      // Agregamos la descripción al cuerpo
      cuerpoTarjeta.appendChild(descripcion);
    });
  } else {

    const contenedor = document.getElementById('contenedor');
    const mensajeError = document.createElement('div');

    mensajeError.setAttribute('class', 'alert alert-danger');
    mensajeError.textContent = `Ha ocurrido un error con código ${request.status}`;

    contenedor.appendChild(mensajeError);
  }
}

request.send();

En cuanto al resultado final, si abres el archivo index.html en tu navegador, deberías ver este resultado:

Finalizando

Y con esto ya hemos terminado la aplicación. Puedes ver la aplicación en funcionamiento en este enlace y también puedeos encontrar el código completo en GitHub.

Existen muchas librerías que te permitirán tener un mejor control sobre las respuestas en formato JSON que recibes de una API. Además, también existen APIs que devuelven contenidos en formato XML, aunque son cada vez menos habituales.

Actualmente es más habitual usar librerías como Axions o la API Fetch, que puedes aprender a usar en esta guía.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

2 comentarios en “Cómo conectarte a una API con JavaScript

  1. Excelente muchas gracias camarada nunca habia usado este metodo para obtener peticiones desde un servidor mas veo que es una excelente alternativa a jquery para comenzar a remplazarlo por vanilla

Responder a El Irvano Cancelar la respuesta

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

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”