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 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
Demonstração dos lançamentos da SpaceX

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
Aplicação do Next.js

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.

Acompanhe com o commit!

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
Registrando a prop 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.

Acompanhe com o commit!

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
Registro dos dados no terminal

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
Registro da prop no console da web

Acompanhe com o commit!

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
Título atualizado da página

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
Página com os lançamentos da SpaceX

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.

Acompanhe com o commit!

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
social-footer-card