46

Consume tu primera API de GraphQL con React.js y Apollo

49149Puntos

hace 3 años

GraphQL es un lenguaje de consulta de datos para APIs. Funciona como alternativa a las API REST convencionales, pero agiliza el desarrollo y cambios que se realizan en el cliente (frontend) porque nos permite obtener solo los datos necesaria.

Ventajas de GraphQL

Las ventajas más notables de GraphQL son las siguientes:

  • Está basado en schemas, lo que te permite describir que esperas recibir como respuesta.
  • Resuelve los problemas de Over fetching (obtener data de más) y Under fetching (obtener data de menos y tener que hacer una llamada extra a otro endpoint).
  • Nuestro único endpoint será /graphql, por lo que no debes preocuparte por hacer un llamado a ninguna otra ruta.
  • Únicamente usamos el método POST

Este blogpost se centra en como hacer consultas o querys a un recurso, dejaremos para otro momento el hacer mutaciones y suscripciones, que son las formas de cambiar y obtener actualizaciones en tiempo real de la data de GraphQL

Por otro lado, Apollo Client es una librería que te ayudará con el manejo de estado cuando consumas un recurso con GraphQL, facilitándonos el obtener la data y consumirla dentro de nuestra aplicación. Solo basta con instalar la librería @apollo/client para adquirir todo el set de herramientas que nos facilita.

Creando nuestra aplicación

Vamos a crear una aplicación consumiendo la API de SpaceX con GraphQL y el set de herramientas que provee Apollo client

Setup

El setup para crear un pequeño proyecto usando GraphQL será el siguiente:

  1. Inicializar un proyecto con React desde 0 con webpack o hacerlo con npx create-react-app [appName]
  2. Instalar graphql y @apollo/client con NPM o yarn
    npm install --save graphql @apollo/client
  3. Instanciar ApolloClient dentro de index.js y envolver nuestra aplicación con él de la siguiente forma:
import React from"react";
import ReactDOM from"react-dom";
import"./index.css";
import App from"./App";
// Hasta aquí tienes la estructura básica de tu archivo index.jsimport {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  gql,
} from"@apollo/client";
// Apollo client provee estas y otras herramientas, como te comenté antes// Más abajo conocerás para que sirve cada unaconst myClient = new ApolloClient({
  uri: "https://api.spacex.land/graphql",
  // La uri será el único lugar al cual harás consultas, ahí estará almacenada toda nuestra data
  cache: new InMemoryCache(),
  // InMemoryCache guarda la información ya consultada para evitar el pedir la misma dos o más veces
});

ReactDOM.render(
  // ApolloProvider permite a toda la App hacer consultas desde cualquier lugar// Algo parecido a lo que se haría con Context.Provider
  <ApolloProvider client={myClient}>
    <App /></ApolloProvider>,
  document.getElementById("root")
);

Crea tu componente base para consumir la data

Este será un componente como cualquier otro que harías con React, los parámetros que recibe se renderizarán para ser mostrados en pantalla, por lo que esto lo puedes customizar como mejor te parezca.

Te dejo aquí abajo el como yo lo hice, los estilos los encontrarás en el Repositorio

// LaunchCard.jsimport React from"react";
import"./css/launch-card.css";

exportconst LaunchCard = ({
  links,
  id,
  details,
  launch_success,
  mission_name,
  launch_site,
  launch_year,
  rocket,
}) => {
  return (
    <divclassName="launch"><divclassName="launch--info"><divclassName="launch--header"><divclassName="launch--id"><span>{id}</span></div><imgsrc={links.flickr_images[0]}alt={rocket.rocket_name} />
          {/* Esta es una pequeña validación para mostrar el mensaje de success o failed 
		    según el valor de launch_success */}
          {launch_success ? (
            <divclassName="launch--status launch-success"><span>Success</span></div>
          ) : (
            <divclassName="launch--status launch-failed"><span>Failed</span></div>
          )}
        </div><divclassName="launch--body"><divclassName="launch--title"><h2>{mission_name}</h2></div><p>Ubication: {launch_site.site_name_long}</p><p>Year: {launch_year}</p></div><divclassName="launch--footer"><h3>{rocket.rocket_name}</h3><span>{rocket.rocket_type}</span></div></div><divclassName="launch--description"><divclassName="launch--details"><p>{details}</p></div><ahref={links.article_link}target="__blank">
          See article
        </a><ahref={links.video_link}target="__blank">
          See video
        </a></div></div>
  );
};

Haz los llamados a la API con graphQL

Llegó el momento de ver de manera práctica el como funciona este lenguaje de consulta.

Esto lo puedes hacer dentro del mismo componente que consume la data, pero, en este caso en particular, lo que se espera recibir es un array y renderizar el componente anterior por cada item del array.

El componente contenedor lo llamaremos LaunchesDetailed.js (Puedes poner cualquier otro nombre sin problema) y su estructura será la siguiente:

Puedes probar hacer las query antes de ponerlas en tu código desde el GraphiQL

// LaunchesDetailed.jsimport React from'react'import { gql, useQuery } from'@apollo/client'// gql nos permite escribir una consulta de GraphQL desde JavaScript plano// Las consultas que hagas a GraphQL tienen que poseer la keyword "query"// Otra facilidad de algunos recursos es que permite definir un límite para no recibir data en excesoconst LAUNCHES_INFO = gql`
  query getLaunches {
    launches(limit: 10) {
	  id
	  mission_name
	  launch_success
	  details
	  launch_year
	  launch_site {
	    site_name_long
	  }
	  links {
	    flickr_images
	    article_link
	    video_link
	  }
	  rocket {
	    rocket_name
	    rocket_type
	  }
	}
  }
`// Puedes consumir más o menos data de esta, en el recurso de arriba está todo con más detalleexportconst LaunchesDetailed = () => {
  // useQuery es el hook que nos permite hacer la consulta de forma sencilla// Nos facilita el crear una vista en los siguientes casos// 1. Tener la data completa// 2. Estar obteniendo la data// 3. Obtener un error en lugar de la dataconst { data, loading, error } = useQuery(LAUNCHES_INFO)

  // En cada caso es necesario mostrar un componente en pantalla o puedes tener errores// Esto ayuda a mejorar tu UI usando Loaders con CSS o mostrar pantallas de errores// más descriptivosif(loading) return<p>Loading... </p>if(error) return<h2>Error</h2>// En el caso de tener la data no es necesario el poner un condicional, ya que se da por// hecho que se tiene sin ningún problemareturn(
    <div className="launches">
      {data.launches.map((item) => (
        // Puedes hacer object destructuring, debido a que en el componente tienes
        // los parámetros con los nombres igual que en GraphQL
        <LaunchCard  key={item.mission_name}  {...item}  />
      ))}
    <div>
  )
}

Une todos tus componentes

Al final, tu componente App.js deberá quedarte muy limpio solo con los componentes que has creado importados en él, en mi caso, este fue el resultado final y tu aplicación deberá mostrarse sin ningún error en pantalla

import { LaunchesDetailed } from"./components/LaunchesDetailed";

functionApp() {
  return (
    <divclassName="App"><h1className="title">SpaceX launches</h1><LaunchesDetailed /></div>
  );
}

export default App;
React App spaceX

Visita la demo live aquí
Los estilos no son lo mejor pero se que lo harás mejor que yo 😉

Ya aprendiste una nueva forma de consumir recursos que no es con una API REST y sin tener que preocuparte por las promesas o por poner un solo fetch

Esto es un poco del gran potencial que tiene GraphQL. Esta vez solo lo consumimos, pero aún tiene un par de funcionalidades y herramientas más. Te sugiero ver esta serie de cursos para que tengas un dominio completo sobre este lenguaje de consultas y puedas combinarlo como todo un experto o experta en React.

#NuncaParesDeAprender

Leonardo de los angeles
Leonardo de los angeles
LeoCode0

49149Puntos

hace 3 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
5
3242Puntos
3 años

Excelente aporte, actualmente estoy usando NextJS y me encantaría implementar GraphQL

4
39069Puntos
3 años

Me gustan estos Mini projectos y este es muy bueno 😄, gracias!!!

4
5959Puntos
3 años

Un tutorial bastante genial, la verdad me ha llamado mucho la atención aprender graphql, siempre he estado acostumbrado a rest y puede que al principio cueste, sin embargo vamo a darle!

4
410Puntos
3 años

muy buen post, gracias por la información.

3
25755Puntos
3 años

Excelente aporte Leo 🚀🔥 , el ejemplo fue muy claro y la API de Space X es muy buena 😍

3
33157Puntos
3 años

Tengo una duda existencial y aprovecho para mencionarla. Si se utiliza graphql y react, donde queda el backend? O cuál sería el stack completo de tecnologías para que estas 2 tecnologías puedan escalar un proyecto?

4
39069Puntos
3 años

El backend es el mismo que utilizas con una API Rest (puede estar desarrollado con Node), la diferencia es que en el lado del backend tambien instalas GraphQL y con ellos manejas la base de datos.

3
19565Puntos
3 años

Justo estoy en introduccion a GraphQL con Gatsby.js y esto me viene a dar energía a nunca parar de aprender. En realidad esto es complejo pero los humanos somos seres complejos, si se puede compañeros. ;D