En este tutorial aprenderas a crear un Frontend de Nextjs que usa Graphql para comunicarse con un backend.

Creación de Proyecto Nextjs

npx create-next-app nextjs-graphql-setup


√ Would you like to use TypeScript? Yes
√ Would you like to use ESLint? Yes
√ Would you like to use Tailwind CSS? Yes
√ Would you like to use `src/` directory? Yes
√ Would you like to use App Router? (recommended) Yes
√ Would you like to customize the default import alias (@/*)? ... No
npm install @apollo/client@rc @apollo/experimental-nextjs-app-support

Crea un archivo en src/lib/client.js

import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client";
import { registerApolloClient } from "@apollo/experimental-nextjs-app-support/rsc";

export const { getClient } = registerApolloClient(() => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      // https://studio.apollographql.com/public/spacex-l4uc6p/
      uri: "https://rickandmortyapi.com/graphql",
      // you can disable result caching here if you want to
      // (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
      // fetchOptions: { cache: "no-store" },
    }),
  });
});

Crea un archivo en lib/apollo-wrapper.js ApolloWrapper:

"use client";

import { ApolloLink, HttpLink } from "@apollo/client";
import {
  ApolloNextAppProvider,
  NextSSRInMemoryCache,
  SSRMultipartLink,
  NextSSRApolloClient,
} from "@apollo/experimental-nextjs-app-support/ssr";

function makeClient() {
  const httpLink = new HttpLink({
    // https://studio.apollographql.com/public/spacex-l4uc6p/
    uri: "https://rickandmortyapi.com/graphql",
  });

  return new NextSSRApolloClient({
    cache: new NextSSRInMemoryCache(),
    link:
      typeof window === "undefined"
        ? ApolloLink.from([
            new SSRMultipartLink({
              stripDefer: true,
            }),
            httpLink,
          ])
        : httpLink,
  });
}

export function ApolloWrapper({ children }) {
  return (
    <ApolloNextAppProvider makeClient={makeClient}>
      {children}
    </ApolloNextAppProvider>
  );
}

en app/layout.js:

import { Inter } from "next/font/google";
import "./globals.css";
import { ApolloWrapper } from "@/lib/apollo-wrapper";

const inter = Inter({ subsets: ["latin"] });

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ApolloWrapper>{children}</ApolloWrapper>
      </body>
    </html>
  );
}

en src/app/page.js

import { getClient } from "@/lib/client";
import { gql } from "@apollo/client";

async function loadData() {
  const query = gql`
    query {
      characters(page: 2, filter: { name: "rick" }) {
        info {
          count
        }
        results {
          name
          image
        }
      }
    }
  `;

  const { data } = await getClient().query({ query });
  console.log(data);
  return data.characters.results;
}

async function HomePage() {
  const characters = await loadData();
  console.log(characters);

  return (
    <div className="grid grid-cols-3">
      {characters.map((character) => {
        return (
          <div
            className="flex flex-col items-center justify-center"
            key={character.name}
          >
            <img src={character.image} alt={character.name} className="w-1/2" />
            <p>{character.name}</p>
          </div>
        );
      })}
    </div>
  );
}
export default HomePage;

en src/app/client/page.js:

"use client";

export const dynamic = "force-dynamic";

import { gql } from "@apollo/client";
import { useSuspenseQuery } from "@apollo/experimental-nextjs-app-support/ssr";

const query = gql`
  query {
    characters(page: 2, filter: { name: "rick" }) {
      info {
        count
      }
      results {
        name
        image
      }
    }
  }
`;

export default function ClientPage() {
  const { data } = useSuspenseQuery(query);

  return (
    <div className="grid grid-cols-3">
      {data.characters.results.map((data, i) => (
        <div key={i}>
          <h3>{data.name}</h3>
          <img src={data.image} alt={data.name} />
        </div>
      ))}
    </div>
  );
}

Instalación de Apollo GraphQL

Más Recursos

Esta es una lista mas extensa de otros recursos: