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.
Las ventajas más notables de GraphQL son las siguientes:
/graphql
, por lo que no debes preocuparte por hacer un llamado a ninguna otra ruta.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.
Vamos a crear una aplicación consumiendo la API de SpaceX con GraphQL y el set de herramientas que provee Apollo client
El setup para crear un pequeño proyecto usando GraphQL será el siguiente:
npx create-react-app [appName]
graphql
y @apollo/client
con NPM o yarnnpm install --save graphql @apollo/client
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")
);
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>
);
};
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>
)
}
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;
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
Excelente aporte, actualmente estoy usando NextJS y me encantaría implementar GraphQL
Me gustan estos Mini projectos y este es muy bueno 😄, gracias!!!
cool
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!
muy buen post, gracias por la información.
Excelente aporte Leo 🚀🔥 , el ejemplo fue muy claro y la API de Space X es muy buena 😍
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?
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.
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
esta geniral
Excelente porte muchas gracias