¿Como conectar y consumir un API con ReactJs? Parte 2 y ejemplo practico.

Facundo N. Herrera
10 min readAug 16, 2018

--

Para ir a la parte 1:
¿Como conectar y consumir un API con Reactjs? Parte 1.

Para ir a parte 3:
**En proceso de desarollo!**

# Configuracion de servicios e implementación de librería AXIOS — Parte 2

En esta parte ya utilizaremos la librería basada en promesas que consumirá y se conectará con el API de yts. Para este tutorial utilizaremos Axios, librería casi estandar en el uso de conexiones en librerias progresivas como VueJs y Reactjs. Tambien es posible utilizarlo con VanillaJS si así lo deseamos.

[Link a la documentación de Axios]

Lo primero que realizaremos es ir a la carpeta llamada “Services”, en ella crearemos un archivo llamado “.config”.

Lo que tendrá el archivo config será primordialmente un llamado a la librería Axios, y la conexión con el URI de nuestra API.

  • Primeramente vamos a importar AXIOS en nuestro archivo .config
  • Luego vamos a crear una variable constante con la dirección de YTS API.
  • Creamos una variable, la cual exportaremos por defecto posteriormente, que será una instancia de axios, en ella setearemos el valor “baseURL” el cual nos servirá en el futuro para los accesos a los datos del API.
Configuración del config.js

En la instancia lo que podremos hacer en el futuro es modificar las configuraciones que se adecúen a nuestro desarollo, entre ellos están los accesos de tipo CROSS ORIGIN, Seteos de Headers, Enviar tokens.
Más información en [https://github.com/axios/axios#user-content-creating-an-instance]

Luego de la creación de nuestra configuración basica de axios, lo que haremos es crear los archivos independientes de servicios. Como nosotros solo tendremos conexión a las peliculas y sus detalles haremos un unico archivo de servicios, esta será llamada MoviesService.js.

Los servicios no serán más que funciones de tipo promesas, esto para conectarnos con las APIs de manera ASINCRONA y poder esperar posteriormente a que estas sean resueltas para utilizar estos datos.

Existen varias maneras de encarar los servicios:

  • Podemos hacer una clase ES6 en donde crearemos metodos de tipo promesas e instanciar la clase en el componente donde utilizaremos el servicio.
  • Podemos hacer una clase ES6 igual que el ejemplo anterior, solo que esta vez con metodos tipo “static” lo que nos evitaría tener que hacer una instancia de la clase.
  • Entre otras..

Pero la que se hará en el tutorial es crear un objeto en donde se ejecutarán funciones en sus propiedades para ahorrarnos la instancia y las funciones static.

Vamos a crear el fichero llamado “MovieServices” de la siguiente manera:

Como se ve en el ejemplo, se está creando un objeto el cual posee dos funciones de tipo promesa, la razón es porque cuando hagamos la llamada a la API esta nos devolverá de manera asincrona los datos.

Para aprender más sobre promesas podemos ingresar a https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Usar_promesas

Los objetivos de cada función son:

GetAll => Función que nos traerá el listado de todas las peliculas

Get => Función que recibirá un ID como parametro y nos traerá el detalle de esa pelicula en especifico.

Como el API de yts está muy bien documentada podemos ver que tiene dos URI diferentes, una para traer un listado de peliculas y otro para traer un movie en especifico.

Más adelante ustedes podrán jugar con los valores del API, pero para efectos del tutorial vamos a utilizar de la siguiente manera las URI.

  • List Movies => Traerá un listado de peliculas
  • Movie Detail => Traerá individualmente las movies. Esta URI recibe un valor ID.

Lo que haremos será crear un objeto donde volcaremos estas URI para poder acceder. Una buena practica sería crear dentro de la carpeta _Services_ un archivo llamado “endpoints.js” para poder tener más organizado y documentado, pero en este ejemplo lo declararemos en el mismo archivo para que se vea más claro.

const MOVIES_ENDPOINTS = {
LIST_MOVIES: "list_movies.json", //URI para llamar a todas las peliculas
MOVIE_DETAIL: "movie_details.json?movie_id=" //URI para llamar a una pelicula en especifico.
}

Ahora si ya podremos hacer uso de las funciones de tipo promesas creadas anteriormente para conectar con la librería axios.

Para hacer uso de la instancia de axios es importante saber con anterioridad que axios nos da una seríe de metodos con los cuales nosotros podemos realizar facilmente peticiones HTTP con diferentes verbos.

Para quienes no estén familiarizados, HTTP es un protocolo de comunicación en la web, esta tiene una serie de VERBOS con los cuales podremos realizar X acción dependiendo de Y verbo. Para expandir los conocimientos con respecto a esto les dejo el link https://developer.mozilla.org/es/docs/Web/HTTP/Methods

Los metodos que nos provee Axios son de tipo promesas, ellos son:

//Get
axios.get(endpoint)
.then()
.catch
//Post
axios.post(endpoint,payload)
.then()
.catch()
//Put
axios.put(endpoint,payload)
.then()
.catch()
//Delete
axios.delete(endpoint)
.then()
.catch()

El parametro “endpoint” es la URI a donde realizará la petición.

El parametro “payload” es un nombre estandar para llamar al recurso que enviarémos como petición.

Ejemplo:

let payload = {
nombre: "Facundo",
apellido: "Herrera"
}
let endpoint = "http://www.dominio.com/api/";
axios.post(endpoint,payload)
.then(
response => response.data //response es un objeto, entre los datos que devuelve está el data que es nuestra respuesta del servidor en sí.
).catch(
err => err
)

Como vemos en el ejemplo el endpoint es la URI completa, pero como nosotros tenemos una instancia de axios y a esta seteamos un valor llamado “baseURL” podemos llamar solo a la porción de la URI que tiene relación con la petición que necesitamos, sería como una concatenación del dominio más el metodo a donde apuntar.

//Ejemplo sin base URL configurada.axios.get("https://www.dominio.com/api/usuarios");///##Ejemplo CON baseURL configurada.const API = axios.create({
baseURL: 'https://www.dominio.com/api'
});
API.get("/usuarios");

Siguiendo con el tutorial, ahora podremos hacer un llamado de nuestra instancia e implementarlo en el objeto ya que tenemos nuestros conocimientos necesarios para seguir.

MoviesService.js // Configuración de los endpoints.
MoviesService.js // Agregando los endpoints y finalizando las promesas

En el inicio del archivo podemos ver como tenemos una constante llamada “Movies_Endpoints” el cual es un objeto que llamaremos en las funciones a modo endpoint.

En las funciones vemos como trabajamos con las promesas, en ella hacemos uso de los valores resolve cuando se termine la promesa axios satisfactoriamente y reject cuando catcheamos el error en la petición.

[Link directo en Github a MovieService.js.]

Para los que desconozcan como funcinan las promesas, el resolve es una funcion tipo callback que recibe un parametro que será devuelto cuando la petición finalice de manera satisfactoria, el reject es exactamente igual solo que debemos enviarlo cuando no sea satisfactoria la devolución, es por ello que posteriormente cuando usemos esta funcion promesa vamos a utilizar los metodos “then()” que capturará el valor del resolve y “catch()” que capturará el valor devuelto por el reject.

Como notarán, hay una leve diferencia en como obtenemos el valor del listado y como obtenemos de una pelicula individual, esto responde únicamente a la estructura de respuesta en uno y el otro, no siempre un recurso devolverá de la misma manera que otro y es por eso que es tan importante la documentación y el debuggeo.

Llegado a este punto ya podríamos decir que conocemos como conectar ReactJS con una API externa, ya que solo nos faltaria saber como consumirlo o “leerlo” desde nuestro desarollo. Por lo tanto quienes tengan ya un poco de experiencia en el desarollo con ReactJs podrían saltarse la siguiente parte porque será relacionada más a explicaciónes sobre como renderizar nuestra información y un pequeño “Look and feel” de nuestros componentes.

Todo lo restante con respecto a axios se puede consultar en la documentación, pero me gustaría aclarar 2 cuestiones para que no existan confusiones en el futuro de su desarollo.

Lo primero es que las peticiónes HTTP nos devuelven una Response, la cual es una estructura compuesta por una serie de parametros, lo que hace Axios en su promesa es presentarnos esta response y enviarla como parametro al then() o catch() con una estructura diferente de acuerdo al valor que capturemos en el status de esta response.

La estructura que tiene Axios es basicamente esta cuando el response es satisfactorio:

{
status: 200, // Status code HTTP, satisfactoriamente va desde 200 a 299
data: {}, //Objeto o array de objetos, de tipo JSON, esta es la información que tomamos y la más importante.
statusText: "", //String, mensaje que nos devuelve el servidor como guia.
}

Por lo tanto en caso de hacer un match correcto podemos debugguear de la siguiente manera:

axios.get('/user/12345')
.then((response) => {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);

});

Como se puede apreciar el response.data nos devolverá la respuesta en si del API, la que generalmente es llamada _Content_. El content es la devolución de los datos en si por parte del servidor, por lo tanto nos lleva a la segunda aclaración.

La devolución de la data dependerá de como está desarollada el API. Esto significa que muchas veces podría devolvernos un objeto con muchas propiedades a la cual acceder o incluso un array de objetos a modo de listado, es por ello que lo ideal sería que tengamos acceso a la documentación o en su defecto deberemos debuggear mediante salidas de consola para ver que datos nos trae y cuales nos sirven.

Entendido esto, lo que vamos a hacer ahora es mostrar a modo de ejemplo un render del listado de las peliculas, cabe aclarar que en la siguiente parte se realizará un ejemplo más completo y con la parte visual resuelta, pero para esta sección creo que sería bueno concluir con un uso real de las peticiónes.

# Pequeño ejemplo Practico de conexión con API.

Primeramente crearemos dentro de la carpeta ‘Screens’ dos carpetas adicionales, la primera será llamada Container y la segunda Components, esto para seguir un patrón de diseño.

Dentro de la carpeta Components están aquellos llamados “Dumb” o no-inteligentes, estos por lo general son componentes sin estado que se encargan de la UI. En esta carpeta vamos crear dos archivos:

  • El primero será llamado “MovieLayout” para darle estilos en el futuro, pero tambien para poder tener mejor estructurados nuestros componentes. Este componente renderizará sus childrens. Un children es un componente que está incluido en otro, por ejemplo:
<ComponentePadre>
<ComponenteHijo />
</ComponentePadre>
  • El segundo componente que crearemos será uno llamado ListMovies. Este es un componente que renderizará un listado de movies que vendrá via props, aquí el codigo completo del mismo.

Finalizada la creación de dumb components, procederemos a la creación de containers.

Dentro de la carpeta Container es donde vamos a llamar a los componentes “smart” o inteligentes y es con los cuales vamos a hacer los llamados a nuestro servicio. Dentro de esta carpeta lo que haremos será

  • Crearemos el container llamado “MovieContainer”. Este se encargará de toda la logica y nada relacionado con la UI.
  • Importaremos todos los componentes necesarios en la UI, estos por ahora solo son <MovieLayout/> y <ListMovies/>.
  • Crearemos un state, en el es donde actualizaremos los datos. Tendrá el siguiente formato:
state = {
data: [], //Array de datos que actualizaremos cuando hagamos el llamado a la API.
}
  • Crearemos un metodo que se conectará con el servicio, cuando obtengamos la resolución exitosa de la promesa actualizaremos el estado de nuestro container.
  • Ejecutaremos al metodo creado anteriormente dentro del ciclo de vida de nuestro container, este será ejecutado en el ComponentDidMount.
  • Finalmente pasaremos la propiedad ‘data’ del estado del container como propiedad del componente tal como <ListMovies data={this.state.data}/>, esto para poder tomarlo y renderizarlo como dijimos anteriormente.
  • Quedando el Container de la siguiente manera:
Importando los componentes necesarios.
Declaración del componente y creación del state y funciones.
Render de nuestra aplicación.

Quedando nuestra estructura de proyecto de la siguiente manera.

Estructura actual de nuestro proyecto.

Finalmente solo nos quedaría renderizar con ReactDom.render nuesto componente, esto se realiza en el ‘index.js’ de nuestro proyecto.

Render del componente.

Ahora cuando levantemos el proyecto via “npm run start” veremos que nuetro proyecto se conecta con el API de YTS y nos permite imprimir el listado de peliculas en nuestro componente

Listado de peliculas.

Concluimos con la parte 2 de nuestro mini-tutorial. Como dije anteriormente, en este punto quien ya tenga un poco de experiencia en Reactjs ya podrá seguir por su cuenta ya que lo proximo solo será un poco de look and feel ayudado Materializecss para que nuestro proyecto quede más armonico.

Esta parte fue la más larga ya que traté de explicar de una manera abarcativa como funciona Axios, algunas cuestiones de JS, estructuras en nuestro proyecto y algunas cosas basicas de Reactjs. En caso de que no haya quedado claro algo agradeceré que lo comenten abajo para así poder agregar la explicación a esta serie.

El repositorio de Github es el siguiente: https://github.com/faherrera/kakuvideo

--

--

Facundo N. Herrera

Intentando programar para conocer a Morfeo. Crecer recordando aquel verso de Machado, hoy es siempre todavía. https://faherrera.github.io