Artigo original: How to Fetch GraphQL Data in Next.js with Apollo GraphQL
O Next.js tem tido um crescimento constante como uma ferramenta obrigatória para desenvolvedores criarem aplicações em React. Parte do que faz ele bom são as suas APIs de obtenção de dados (em inglês, data fetching) que solicitam dados para cada página. Como, porém, podemos usar essa API para fazer queries do GraphQL para nossa aplicação?
- O que é o GraphQL?
- O que é o Apollo GraphQL?
- Solicitando dados no Next.js
- O que vamos criar?
- Passo 0: Criando uma aplicação do Next.js
- Passo 1: Adicionando o Apollo GraphQL em uma aplicação do Next.js
- Passo 2: Adicionando dados em uma página do Next.js com getStaticProps
- Passo 3: Recuperando dados com uma query do GraphQL em Next.js usando o Apollo Client
- Passo 4: Adicionando dados de lançamento da SpaceX na página
O que é o GraphQL?
O GraphQL é uma query language e runtime que fornece uma maneira de interagir com uma API, diferente daquilo que você esperaria de uma API REST tradicional.
Quando dados são solicitados, ao invés de fazer uma requisição GET para uma URL para pegar esse dado, um endpoint do GraphQL recebe uma "query" (consulta). Essa query indica quais dados queremos recuperar, seja um conjunto de dados completo ou apenas uma parte deles.
Seus dados poder se parecer com isto:
Movie { "title": "Sunshine", "releaseYear": "2007", "actors": [...], "writers": [...] }
Pode ser que você queira apenas pegar o título e o ano em que o filme foi lançado. Para isso, você poderia enviar uma query assim:
Movie { title releaseYear }
Isso recuperaria apenas os dados de que você precisa.
A parte legal é que você também pode criar relações complexas entre dados. Com uma única query, você poderia ainda pedir dados de diferentes partes do banco de dados, o que tradicionalmente levaria a múltiplas solicitações para a API REST.
O que é o Apollo GraphQL?
No seu núcleo, o Apollo GraphQL é uma implementação do GraphQL que auxilia a trazer os dados como um grafo.
O Apollo também oferece e mantém um client de GraphQL, que é o que vamos usar. Ele permite a interação programática com uma API do GraphQL.
Usando o client do Apollo GraphQL, seremos capazes de fazer solicitações para uma API do GraphQL de modo similar ao que você esperaria de um client para APIs REST.
Solicitando dados no Next.js
Quando estamos solicitando dados no Next.js, há algumas formas de se recuperar esses dados.
Primeiramente, você poderia fazer o client executar a solicitação quando a página carregar. O problema disso é que você está colocando o fardo no client de achar tempo para fazer essas solicitações.
APIs do Next.js, como getStaticProps
e getServerSideProps
, permitem que você colete dados em diferentes momentos do ciclo de vida, nos dando a oportunidade de fazer uma aplicação complemente estática (vídeo em inglês) ou que ela seja renderizada do lado do servidor. Essas funções servem os dados que já foram renderizados na página diretamente no navegador.
Usando um desses métodos, somos capazes de solicitar dados juntamente com nossas páginas e de injetar esses dados como props diretamente na nossa aplicação.
O que vamos criar?
Vamos criar uma aplicação do Next.js que mostra os últimos lançamentos da SpaceX.
![spacex-launches-demo](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/spacex-launches-demo.jpg)
Utilizaremos a API mantida pela SpaceX Land para fazer uma query do GraphQL que pega os últimos 10 voos. Usando getStaticProps, vamos fazer a solicitação na build, o que significa que nossa página será renderizada estaticamente com nossos dados.
Passo 0: Criando a aplicação do Next.js
Usando Create Next App, podemos rapidamente começar uma nova aplicação do Next.js, que usaremos para navegar no código imediatamente.
No terminal, execute o comando:
npx create-next-app my-spacex-launches
Nota: você não precisa usar my-spacex-app
, sinta-se livre para substituir por qualquer nome que você deseje dar para o projeto.
Depois de rodar o script, o Next.js vai configurar um novo projeto e instalar as dependências.
Uma vez terminado, você pode começar o servidor de desenvolvimento:
cd my-spacex-launches
npm run dev
Esse comando iniciará um novo servidor em http://localhost:3000, onde você pode visitar a sua nova aplicação!
![new-nextjs-app-1](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/new-nextjs-app-1.jpg)
Passo 1: Adicionando o Apollo GraphQL em uma aplicação do Next.js
Para começar a fazer uma query do GraphQL, vamos precisar de um client do GraphQL. Vamos utilizar o client Apollo GraphQL para fazer nossas queries para o servidor do GraphQL da SpaceX.
Novamente, no terminal, execute o seguinte comando para instalar as nossas novas dependências:
npm install @apollo/client graphql
Esse comando vai adicionar o Apollo Client e também o GraphQL, que precisaremos para formar uma query do GraphQL.
Uma vez que a instalação completar, estaremos prontos para começar a usar o Apollo Client.
Passo 2: Adicionando dados a uma página do Next.js com getStaticProps
Antes de solicitarmos dados com o Apollo, vamos configurar nossa página para sermos capazes de requisitar os dados e, então, passar esses dados como props para nossa página na build.
Vamos definir uma nova função no fim da página, embaixo do nosso componente Home
, chamada getStaticProps
:
export async function getStaticProps() {
// O código vai aqui
}
Quando o Next.js fizer a build da nossa aplicação, ele saberá onde encontrar essa função. Então, quando a exportamos, estamos informando o Next.js que queremos rodar o código daquela função.
Dentro da nossa função getStaticProps
, vamos, em última instância, retornar as props para a página. Para testar isso, vamos adicionar o seguinte na nossa função:
export async function getStaticProps() {
return {
props: {
launches: []
}
}
}
Aqui, estamos passando uma nova prop chamada launches
e estamos definindo a prop como um array vazio.
Agora, de volta para o nosso componente Home
, vamos adicionar um novo argumento desestruturado que servirá como nossa prop e também vamos utilizar o console.log
para testá-la:
export default function Home({ launches }) {
console.log('launches', launches);
}
Se recarregarmos a página, podemos observar que agora estamos imprimindo nossa nova prop launches
, que inclui um array vazio da maneira como definimos.
![nextjs-console-log-launches-array](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/nextjs-console-log-launches-array.jpg)
launches
O interessante disso é que, uma vez que a função getStaticProps
que estamos definindo é assíncrona, podemos fazer qualquer solicitação que quisermos (incluindo uma query do GraphQL) e retorná-la como props para a nossa página, que é o que veremos mais adiante.
Passo 3: Recuperando dados com uma query do GraphQL no Next.js usando o Apollo Client
Agora que nossa aplicação está preparada para adicionar na nossa página e que temos o Apollo instalado, podemos finalmente fazer uma solicitação para pegar nossos dados da SpaceX.
Aqui, vamos usar o Apollo Client, que é o que permite nos conectarmos com o servidor do GraphQL da SpaceX. Faremos nossa solicitação para a API usando o método getStaticProps
do Next.js, nos permitindo criar props dinamicamente para nossa página quando ela é construída.
Primeiramente, vamos importar nossas dependências do Apollo no projeto. No topo da página adicione:
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
Isso incluirá o client do Apollo propriamente dito, InMemoryCache
, que permite ao Apollo otimizar por meio de leitura de um cache, e gql
, que utilizaremos para formar nossa query do GraphQL.
Agora, vamos utilizar o Apollo Client. Para isso, precisamos configurar uma nova instância dele:
Dentro da função getStaticProps
, adicione:
const client = new ApolloClient({
uri: 'https://api.spacex.land/graphql/',
cache: new InMemoryCache()
});
Isso cria uma instância do Apollo Client usando o endpoint da API do SpaceX pelo qual faremos a query.
Com o nosso client, conseguimos finalmente fazer uma query. Adicione o seguinte código abaixo do client:
const { data } = await client.query({
query: gql`
query GetLaunches {
launchesPast(limit: 10) {
id
mission_name
launch_date_local
launch_site {
site_name_long
}
links {
article_link
video_link
mission_patch
}
rocket {
rocket_name
}
}
}
`
});
Isso faz algumas coisas:
- Cria uma query dentro das tag
gql
- Cria uma query request usando
client.query
- Usa
await
para garantir que ele finalize a requisição antes de continuar - Por fim, desestrutura
data
dos resultados, que é onde as informações que precisamos estão armazenadas.
Dentro da query do GraphQL, estamos informando para a SpaceX que queremos pegar launchesPast
, que são os últimos lançamentos da SpaceX, e que queremos os últimos 10 (limite). Dentro disso, definimos os dados que gostaríamos de recuperar.
Se adicionarmos um novo console log depois disso, podemos observar a aparência de data
.
No entanto, uma vez que você recarregar a página, você notará que você não está vendo nada no console do navegador.
getStaticProps
roda durante o processo de build, o que significa que ele roda no node. Portanto, podemos olhar o nosso terminal e veremos os logs:
![logging-static-props-terminal](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/logging-static-props-terminal.jpg)
Depois de ver isso, sabemos que o objeto data
tem uma propriedade chamada launchesPast
, que inclui um array de detalhes de lançamento.
Agora, podemos atualizar o retorno para usar launchesPast
:
return {
props: {
launches: data.launchesPast
}
}
Se adicionarmos nosso console.log
de volta no topo da página para ver a aparência da prop launches
, podemos observar que nossos dados de lançamento agora estão disponíveis como uma prop na nossa página:
![logging-static-props-web-console](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/logging-static-props-web-console.jpg)
Passo 4: Adicionado os dados de lançamento da SpaceX na página
Agora, vamos para a parte legal!
Temos nossos dados de lançamento, que conseguimos recuperar usando o Apollo Client, para solicitar do servidor do GraphQL da SpaceX. Fizemos uma requisição dentro de getStaticProps
, de maneira que conseguimos deixar nossos dados disponíveis como a prop launches
, que contém os dados de lançamento.
Navegando na página, vamos começar tirando proveito do que já existe. Por exemplo, podemos começar atualizando a tag h1
e o parágrafo abaixo dele para algo que descreva nossa página um pouco:
![updated-page-title](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/updated-page-title.jpg)
Depois, vamos utilizar os cards de link que já existem para incluir todos os nossos dados de lançamento.
Para fazer isso, vamos, primeiramente, adicionar um map dentro do grid da nossa página, onde o componente que retornamos é um dos cards, com os dados de lançamento preenchidos:
<div className={styles.grid}>
{launches.map(launch => {
return (
<a key={launch.id} href={launch.links.video_link} className={styles.card}>
<h3>{ launch.mission_name }</h3>
<p><strong>Launch Date:</strong> { new Date(launch.launch_date_local).toLocaleDateString("en-US") }</p>
</a>
);
})}
Podemos também nos livrar do resto dos cards padrão do Next.js, incluindo Documentation e Learn.
![list-of-spacex-launches](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/list-of-spacex-launches.jpg)
Nossa página, agora, inclui os últimos 10 lançamentos da SpaceX e a data do lançamento!
Podemos até mesmo clicar em qualquer um desses cards e, já que vinculamos o link para o vídeo, conseguimos agora ir diretamente para o vídeo ao clicar.
Próximos passos
A partir de agora, podemos incluir qualquer dado adicional de dentro do nosso array launches
na nossa página. A API até mesmo inclui imagens de emblemas da missão, que podemos usar para mostrar imagens bonitas para cada lançamento.
Você também pode adicionar qualquer dado na query do GraphQL. Cada lançamento tem muitas informações disponíveis, incluindo a tripulação do lançamento e mais detalhes sobre o foguete.
https://api.spacex.land/graphql
![jamstack-handbook-banner](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/jamstack-handbook-banner.jpg)
![social-footer-card](https://www.freecodecamp.org/portuguese/news/content/images/2024/05/social-footer-card.jpg)