Documentos de Académico
Documentos de Profesional
Documentos de Cultura
¡Comencemos!
_ 1
www.desafiolatam.com
¿Qué aprenderás?
● Consultar múltiples API utilizando Ajax y promesas para controlar el orden de los
llamados.
● Determinar cuáles métodos utilizar para manejar el flujo al trabajar con Promesas.
Introducción
En el mundo de la web cada día navegamos por distintas páginas, ejecutamos aplicaciones,
jugamos en los dispositivos, nos logueamos en nuestras aplicaciones favoritas como
Instagram, Facebook, Twitter, vemos películas o series en Netflix, entre otros. Cada vez que
realizamos una acción en un sitio web que implique ver o manejar datos dinámicos
estaremos utilizando APIs para enviar y traer datos desde el servidor.
Por ende, en este capítulo veremos cómo consultar y traer datos desde fuentes externas
(APIs), además, que podemos hacer con estos datos que nos entrega la fuente de
información externa y cómo manejar los errores en el caso de existir, lo cual es de suma
importancia para todo programador frontend o backend, saber como enviar o solicitar
información a una API, además de interactuar dependiendo de la respuesta que retorne la
API. De aquí la importancia del contenido que aprenderás en esta lectura, el cual, gira en
torno al trabajo con fuentes de información externas a nuestro código y te transforma en
todo un profesional desarrollando sitios web que utilicen información dinámica de terceros.
_ 2
www.desafiolatam.com
¿Qué es una API?
Los navegadores también poseen APIs, llamadas WEB APIs y que pueden ser accedidas a
través de JavaScript y que permiten realizar muchas tareas en él mismo, así como también
permite acceder a los recursos del protocolo HTTP para acceder a APIs externas con la WEB
API XMLHttpRequest. Las WEB APIs no son más que funciones que aportan los
navegadores para interactuar con los datos que este proporcione o del entorno en que se
encuentre. Por nombrar algunas, tenemos Geolocation, XMLHttpRequest, setTimeout,
Canvas, Audio, WEBRTC, Notifications, entre otras.
_ 3
www.desafiolatam.com
SOAP (Simple Object Access Protocol)
Como su sigla lo indica es un Protocolo Simple de Acceso a Objetos y sirve para que dos
procesos puedan comunicarse intercambiando datos XML. Actualmente se usa para
exponer servicios web a través del protocolo HTTP. Soporta sólo XML como formato de
datos y se rige por un estricto estándar de mensajes, con reglas establecidas para realizar
solicitudes y respuestas. En consecuencia, la estructura de los mensajes SOAP sería así:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>.
_ 4
www.desafiolatam.com
REST (Representational State Transfer)
Representational State Transfer o Transferencia de Estado Representacional, es cualquier
interfaz entre sistemas que use HTTP para obtener datos o generar operaciones sobre esos
datos en todos los formatos posibles, como XML y JSON. Actualmente se utiliza el mismo
patrón, pero sin el uso del estado y éste trabaja sobre el protocolo HTTP, en conjunto con la
Interfaz de Programación de Aplicaciones (API) y en el que se contribuye en tener mayor
confiabilidad, eficiencia y escalabilidad. A una aplicación se le dice RESTful cuando contiene
estas características.
La arquitectura REST define algunas restricciones o características para ser utilizada, como
el caso de: Cliente/Servidor, Sin estado, Caché, Sistema de capas, Interfaz uniforme y
Código bajo demanda.
Cliente/Servidor
Corresponde a la separación de Cliente/Servidor, cada uno debe manejar sus recursos, el
cliente debe manejar la interfaz y el servidor el almacenaje de los datos. Con esto se mejora
la portabilidad de las interfaces de usuario y escalabilidad para los componentes de los
servidores, ya que no deben preocuparse por lo que pasa en la interfaz de usuario.
_ 5
www.desafiolatam.com
Sin estado
Cada petición que se realice desde el cliente al servidor, deberá contener toda la información
necesaria para que el servidor comprenda lo que se está solicitando y no deberá haber
ningún dato guardado con anterioridad y en el que pueda revisarlos.
_ 6
www.desafiolatam.com
Caché
Las peticiones que se realicen podrán o no ser “cacheables”, dependerá si el cliente le
otorga el permiso al servidor para obtener estas respuestas en caso de hacer las mismas
solicitudes.
Interfaz uniforme
La idea de utilizar una interfaz uniforme nace de poder estandarizar solicitudes de datos, por
lo que no sería necesario hacer solicitudes de tipo createUser, updateProduct, removeTicket,
etc. La interfaz de REST tiene un diseño eficiente para el manejo de grandes volúmenes de
datos y con esto se optimiza la web.
● Identificación de recursos
● Manipulación de recursos a través de sus representaciones
● Mensajes auto-descriptivos
● Hipermedios como el motor del estado de la aplicación.
_ 7
www.desafiolatam.com
El servidor siempre retornará el estado de la operación y será 200 si fue correcta, en caso de
ser cualquier otro número, indicará que algo ocurrió de una forma no esperada, y el
resultado de ésta.
Sistema de capas
La idea de tener un sistema de capas es aumentar la escalabilidad de las aplicaciones,
separando por componentes y limitando su comportamiento a lo que debe realizar para
complementar todo el sistema.
_ 8
www.desafiolatam.com
API REST
El término API REST significa utilizar una API para acceder a aplicaciones backend, de
manera que esa comunicación se realice con los estándares definidos por el estilo de
arquitectura REST. En efecto, lo que utilizamos actualmente para manipular los datos es el
estándar API REST, que es la combinación de API y REST, haciendo uso del protocolo HTTP y
poder realizar el envío y recepción de datos al servidor.
Por otra parte, para realizar el envío y recepción de datos se utilizan las especificaciones
más importantes del protocolo HTTP que son GET, POST, PUT, DELETE. Esto se utiliza en un
entorno cliente/servidor, en el que el cliente realiza las peticiones y es el server quien
procesa las solicitudes. Todas las solicitudes cuentan con una URL, el tipo y los datos que
se requiere enviar.
Tipos de solicitudes
● GET: Se utiliza para obtener información. Se le puede pasar parámetros a través de la
misma URL.
● POST: Se usa para agregar nuevos datos. Los datos deben enviarse a través del
Body de la solicitud.
● PUT: Sirve para actualizar datos y éstos deben enviarse en el body de la solicitud.
● DELETE: Nos indica que queremos eliminar algo. Los datos pueden enviarse en la
URL o en el body de la solicitud.
_ 9
www.desafiolatam.com
Datos
Los datos pueden ser establecidos en el formato según la herramienta que se esté
utilizando para realizar las solicitudes a la API. Las APIs REST no son lenguaje dependientes,
por lo que se pueden crear con cualquier lenguaje de servidor como JavaScript (Node), PHP,
Python o Java, por nombrar algunos, la respuesta puede ser devuelta en cualquier formato,
pero por compatibilidad se utiliza JSON o XML.
Consumir APIs
Las APIs se encargan de manejar nuestras peticiones desde el browser y devolvernos los
datos que les solicitamos para que podamos mostrarlos en la web. Cuando le indicamos al
browser que realice una petición a la API mediante una acción, por ejemplo un click en algún
botón o en la carga de una url, entonces realizamos una solicitud mediante cualquier
herramienta que permita hacer solicitudes http como axios, fetch, entre otros. En los
ejemplos que se desarrollarán a lo largo de este capítulo, se utilizará la WEB API fetch para
hacer los request y manejar datos, ya que ofrece una interfaz estándar de uso de Ajax para
el desarrollo frontend, a la vez que permite usar promesas y manejar la respuesta a esa
promesa con los métodos then y catch. Todo esto nos facilita la organización del código
asíncrono en las aplicaciones creadas.
Para consultar y enviar datos utilizaremos la página JSONPlaceholder, que nos permite
extraer y enviar datos, además de utilizarlo como API REST para hacer pruebas o prototipos.
Los datos devueltos por esta API son sólo de prueba y no datos reales. Así mismo, los
recursos que tiene el sitio para utilizar son:
_ 10
www.desafiolatam.com
Ejercicio guiado: Solicitud a una API
● Paso 1: Crear una carpeta en tu lugar de trabajo favorito y dentro de ella crea dos
archivos, un index.html y un script.js. Mientras que en el index.html, debes escribir la
estructura básica de un documento HTML como se muestra a continuación:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Conexión API</title>
</head>
<body>
<h4>Conexión API - Fetch</h4>
<script src="script.js"></script>
</body>
</html>
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => console.log(json))
_ 11
www.desafiolatam.com
● Paso 3: Ejecutar el index.html en el navegador web y observar el resultado en la
consola, nos debe mostrar un arreglo con 10 objetos. Cada objeto debe contener la
información (ficticia) de cada usuario.
Una vez obtenidos estos datos ya podemos hacer que se visualicen en nuestra página,
mediante grillas, formularios, o cualquier otro componente de HTML y CSS.
Existen ocasiones que para solicitar datos a una API, dependemos de algunos valores que
nos retornan otras APIs y para esto necesitamos solicitar datos a múltiples APIs en forma
secuencial. Para ello, implementaremos el método fetch pero esta vez trabajado de forma
asincrónica con Async / Await.
_ 12
www.desafiolatam.com
Ejercicio guiado: Múltiples solicitudes
● Paso 1: Crear una carpeta en tu lugar de trabajo favorito y dentro de ella crea dos
archivos, un index.html y un script.js. Mientras que en el index.html, debes escribir la
estructura básica de un documento HTML como se muestra a continuación:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">}
<title>Conexión API</title>
</head>
<body>
<h4>Solicitud de múltiples APIs en secuencia</h4>
<script src="script.js"></script>
</body>
</html>
// bloque 1
const baseUrl = 'https://jsonplaceholder.typicode.com';
// bloque 2
const request = async () => {}
_ 13
www.desafiolatam.com
// bloque 3
const getPosts = async () => {}
// bloque 4
const getUser = async () => {}
// bloque 5
getPosts().then(() => {})
● Paso 3: Trabajando ahora en el bloque 2, la función request debe recibir una URL
como parámetro para poder consultar mediante el método fetch la API de acuerdo a
la URL recibida, logrando así traer y retornar la información. A la consulta de la API y
a la transformación de datos a JSON se le agrega la expresión await para completar
la función asíncrona.
// bloque 2
const request = async (url) => {
const results = await fetch(url)
const response = await results.json()
return response;
}
● Paso 4: En el tercer bloque de código, se crea o construye la URL para consultar los
posts de la API, interpolando a la URL base creada anteriormente el término posts.
// bloque 3
const getPosts = async () => {
const url = `${baseUrl}/posts`;
return request(url);
}
● Paso 5: En el cuarto bloque, se creará la dirección URL para poder consultar los
usuarios por individual. Por consiguiente, esta función recibe como parámetro el id
que se desea consultar, además se construirá la URL interpolando el término
“/users/” y el parámetro recibido “id”, retornando la URL construida a la función
request creada anteriormente.
// bloque 4
const getUser = async (id) => {
const url = `${baseUrl}/users/${id}`;
return request(url);
}
_ 14
www.desafiolatam.com
● Paso 6: Ya el último bloque, se encargará primeramente de ejecutar la función
denominada getPosts, para poder obtener todos los 100 post que proporciona la
API. Luego cuando llegue la información, se deben extraer los ids de los usuarios en
un arreglo aparte. Esto se hace con el propósito de recopilar los ids de los usuarios
para posteriormente poder solicitar toda la data de un usuarios a la vez. Finalmente
con ayuda de Promise.all y del map, se puede ir pasando el id de cada usuario a la
función getUser para solicitar a la API la información de cada usuario en particular.
// bloque 5
getPosts().then(posts => {
const usersIds = posts.map(p => p.userId);
const setOfUsers = new Set(usersIds);
const users = [...setOfUsers];
Promise.all(users.map(userId => getUser(userId)))
.then(response => console.log(response))
});
A veces es necesario realizar múltiples llamadas a la vez para obtener lo que necesitamos
mostrar, tal cual como cuando explicamos Promise.all en Promesas (Promise) del capítulo
anterior.
_ 15
www.desafiolatam.com
Ejercicio guiado: Publicaciones de un usuario
● Paso 1: Crear una carpeta en tu lugar de trabajo favorito y dentro de ella crea dos
archivos, un index.html y un script.js. Mientras que en el index.html debes escribir la
estructura básica de un documento HTML como se muestra a continuación:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Conexión API</title>
</head>
<body>
<h4>Solicitud de múltiples APIs a la vez</h4>
<script src="script.js"></script>
</body>
</html>
// bloque 1
const baseUrl = 'https://jsonplaceholder.typicode.com';
// bloque 2
_ 16
www.desafiolatam.com
const request = async () => {}
// bloque 3
const getPosts = async () => {}
// bloque 4
const getUser = async () => {}
// bloque 5
const userId = 1;
Promise.all([getUser(userId), getPosts(userId)]).then().catch()
● Paso 3: Trabajando ahora en el bloque 2, la función request debe recibir una URL
como parámetro para poder consultar mediante el método fetch la API de acuerdo a
la URL recibida, logrando así traer y retornar la información. A la consulta de la API y
a la transformación de datos a JSON se le agrega la expresión await para completar
la función asíncrona.
// bloque 2
const request = async (url) => {
const results = await fetch(url)
const response = await results.json()
return response;
}
● Paso 4: En el tercer bloque de código, se crea o construye la URL par consultar los
posts de la API pero para un usuario en particular, interpolando a la URL base creada
anteriormente el término posts más la identificación para especificar que deseamos
ubicar los post del usuario con un id en específico, ?userId=id. El id será la variable
que declaramos anteriormente en el bloque 5, en este caso será el número 1, pero
puede ser cualquier otro número que corresponda a un usuario.
// bloque 3
const getPosts = async (id) => {
const url = `${baseUrl}/posts?userId=${id}`;
return request(url);
}
_ 17
www.desafiolatam.com
recibido “id”, retornando la URL construida a la función request creada
anteriormente en el segundo bloque.
// bloque 4
const getUser = async (id) => {
const url = `${baseUrl}/users/${id}`;
return request(url);
}
// bloque 5
const userId = 1;
Promise.all([getUser(userId), getPosts(userId)])
.then(resp => {
console.log('resp', resp)
})
.catch(err => console.log('err', err))
_ 18
www.desafiolatam.com
Imagen 9: Resultado de la consola del navegador.
Fuente: Desafío Latam
Como vemos en los resultados, se obtuvo un arreglo con 2 elementos, el primero contiene
los datos del usuario y el segundo contiene un arreglo de 10 elementos con datos de los
posts de ese usuario en particular.
_ 19
www.desafiolatam.com
un script.js. Mientras que en el index.html debes escribir la estructura básica de un
documento HTML como se muestra a continuación:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Conexión API</title>
</head>
<body>
<h4>Solicitud de múltiples APIs a la vez</h4>
<script src="script.js"></script>
</body>
</html>
_ 20
www.desafiolatam.com
● Paso 3: Ahora dentro del último bloque, en el Promise.all, después de recibir y
mostrar la respuesta en la consola del navegador, lo primero que vamos a hacer es
dividir la información en dos partes, como el resultado viene en un arreglo con
espacios, entonces creamos una variable para los post y otra para el usuario,
pasando el elemento correspondiente del arreglo a cada nueva variable. Esto se hace
para poder obtener directamente el objeto en el caso del usuario que contiene toda la
información.
Promise.all([getUser(userId), getPosts(userId)])
.then(resp => {
console.log('resp', resp)
const posts = resp[1];
const user = resp[0];
})
.catch(err => console.log('err', err))
Promise.all([getUser(userId), getPosts(userId)])
.then(resp => {
const posts = resp[1];
const user = resp[0];
const name = user.name;
const address = user.address;
const email = user.email;
const city = address.city;
console.log('name', name);
console.log('address', address.suite, address.street);
console.log('geo', `${address.geo.lat},${address.geo.lng}`);
console.log('email', email);
console.log('city', city);
posts.forEach(element => {
const title = element.title;
const body = element.body;
console.log('title', title);
_ 21
www.desafiolatam.com
console.log('body', body);
});
})
.catch(err => console.log('err', err))
_ 22
www.desafiolatam.com