Next.js에 Apollo Client 적용하기
기본적인 웹 구축이 되었으니 GraphQL을 적용해 볼 차례이다. 이를 위해 Apollo라는 라이브러리를 사용할 건데, GraphQL API 콜을 도와줄 뿐만 아니라 캐싱과 상태관리 등 다양한 이점이 있어 🚀 Apollo Client를 적용해 보기로 했다.
모듈 설치
Apollo Client를 구축하는데 필요한 거의 모든 기능을 가지고 있는 @apollo/client와 GraphQL 쿼리를 파싱해주는 graphql을 설치한다.
$ npm i @apollo/client graphql
Apollo Client 생성하기
먼저, /src/lib 폴더 내에 apolloClient.ts 파일을 생성하고, ApolloClient 인스턴스를 생성한다. 이 때 GraphQL 서버 url이 필요하다.  .env 파일에 BACKEND_URL을 정의하고 아래와 같이 적용했다.
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
  uri: process.env.BACKEND_URL,
  cache: new InMemoryCache()
});
Apollo Client 연결하기
프로젝트 전역에서  ApolloClient에 접근할 수 있게 하기 위해 _app.tsx에 적용해 주겠다. 이전 포스팅에서 만들었던 _app.tsx의 최상위 컴포넌트를 ApolloProvider로 감싸고 이전에 만들었던 client를 props로 넘겨 주면 된다.
...
import {ApolloProvider} from '@apollo/client';
import {client} from '../src/lib/apolloClient';
...
export default function App({Component, pageProps}: AppProps) {
  return (
    <ApolloProvider client={client}>
      <ThemeProvider theme={theme}>
          <GlobalStyle />
          <Component {...pageProps} />
      </ThemeProvider>
    </ApolloProvider>
  );
}
GraphQL API 호출하기
이제 간단한 GraphQL API를 호출해 보자. 먼저 src/graphql/query 폴더를 만들고 index.ts 파일을 생성한다. 생성한 파일 내에 GraphQL 쿼리를 정의 하는데 template literal tag인 gql을 사용한다.
import {gql} from '@apollo/client';
export const TEST_QUERY = gql`
  {
    ping
  }
`;
useQuery 사용하기
@apollo/client에서는 useQuery 라는 아주 강력하고 간단한 hooks를 제공한다.
pages/index.tsx 파일을 아래와 같이 수정하면 GraphQL API가 호출되어 응답값을 받는 것을 확인할 수 있다.
import Link from 'next/link'
import Layout from '../src/components/Layout'
import { useQuery } from '@apollo/client';
import {TEST_QUERY} from '../src/graphql/query';
const IndexPage = () => {
  const { loading, error, data } = useQuery(TEST_QUERY)
  console.log(loading, error, data)
  return (
    <Layout>
      <h1>Hello Next.js 👋</h1>
    </Layout>
  )
}
export default IndexPage
콘솔로그
 
getStaticProps 사용하기
정적/사전 렌더링이 필요한 경우, next.js의 getStaticProps 내에서도 GraphQL API 호출이 가능하다.
import Link from 'next/link'
import Layout from '../src/components/Layout'
import { useQuery } from '@apollo/client';
import {TEST_QUERY} from '../src/graphql/query';
import {client} from '../src/lib/apolloClient'
const IndexPage = (props:any) => {
  console.log(props) // =>  { ping: '👋 pong! 👋' }
  return (
    <Layout>
      <h1>Hello Next.js 👋</h1>
    </Layout>
  )
}
export default IndexPage
export const getStaticProps: GetStaticProps = async () => {
  const {data} = await client.query({
    query: TEST_QUERY,
  });
  return {
    props: data,
  };
};
👩🏻💻 배우는 것을 즐기는 프론트엔드 개발자 입니다
  부족한 블로그에 방문해 주셔서 감사합니다 🙇🏻♀️
in the process of becoming the best version of myself