Next js에서 graphql Apollo 활용한 서비스 개발시작

hyeok·2022년 5월 1일
0

이제 퍼블리싱이 끝나서 서버를 이번 휴일이 많이 붙어있는 일주일동안 붙여야 한다.
기존에 사용하던 graphql, apollo를 next.js에 활용하고자 한다.

기본적으로 내가 개발하는 서비스는 request에 따라 유동적인 요소가 없기 때문에 getStaticProps로 개발하고자 한다.

getStaticProps는 정적 페이지를 개발하는 데 아주 유용한 방법이다. 서버에서 애초에 build할때 백엔드 서버와 통신해서 모든 정보를 가져온 후 프리랜더링 한 이후 CDN을 거쳐 고객에게 보내진다. (CDN은 콘텐츠 전송 네트워크로 데이터 캐싱이 되서 이미지 같은 걸 다룰 때 유용한 서비스다.)

export async function getStaticProps() {
    const { data } = await client.query({
      query: gql`
        query Countries {
          countries {
            code
            name
            emoji
          }
        }
      `,
    });

    return {
      props: {
        countries: data.countries.slice(0, 4),
      },
   };
}

쿼리문을 템플릿 리터럴로 가져와서 쿼리를 날린 이후에 가저온 데이터를 props로 내린다.
아주 간단한 방식이다.

예전에도 다루었지만 이를 통해서

<div className={styles.grid}>
  {countries.map((country) => (
    <div key={country.code} className={styles.card}>
      <h3><a href="#country-name" aria-hidden="true" class="aal_anchor" id="country-name"><svg aria-hidden="true" class="aal_svg" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>{country.name}</h3>
      <p>
        {country.code} - {country.emoji}
      </p>
    </div>
  ))}
</div>

랜더링 하는 부분에서 이렇게 props로 가져온 내용을 뿌리면 된다.

getServerSideProps는 매번 request마다 새로 서버에서 정보를 가져오는 방식이다. 이 경우 CDN에 저장이 안되서 비효율적인 부분이 있다고 한다. 그래서 꼭 실시간 최신화가 필요한 때만 사용하는 게 좋다고 한다.
지금 내가 개발하는 서비스엔 딱히 그런 요소는 없다.
코드는 딱히 getStaticProps랑 다른 부분이 없어서 생략한다.

다음 방법으로는 일반적인 CSR방법이 있다. 이는 우리가 기존에 CRA에서 사용하던 개발 방식과 똑같다. hooks를 활용한다.

function MyApp({ Component, pageProps }) {
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}

아폴로 프로바이더로 감싼뒤

import { useQuery, gql } from "@apollo/client";
import styles from "../styles/Home.module.css";

const QUERY = gql`
  query Countries {
    countries {
      code
      name
      emoji
    }
  }
`;

export default function Countries() {
  const { data, loading, error } = useQuery(QUERY);

  if (loading) {
    return <h2><a href="#loading" aria-hidden="true" class="aal_anchor" id="loading"><svg aria-hidden="true" class="aal_svg" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loading...</h2>;
  }

  if (error) {
    console.error(error);
    return null;
  }

  const countries = data.countries.slice(0, 4);

  return (
    <div className={styles.grid}>
      {countries.map((country) => (
        <div key={country.code} className={styles.card}>
          <h3><a href="#country-name" aria-hidden="true" class="aal_anchor" id="country-name"><svg aria-hidden="true" class="aal_svg" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>{country.name}</h3>
          <p>
            {country.code} - {country.emoji}
          </p>
        </div>
      ))}
    </div>
  );
}

useQuery로 가져온다.

과연 이 CSR방식을 nextjs에서 사용했을 때 어떤 단점이 있는지 궁금하다. 확인해볼 예정이다.

주요 참고: https://www.apollographql.com/blog/apollo-client/next-js/next-js-getting-started/

profile
내가 만든 소프트웨어가 사람들을 즐겁게 할 수 있기 바라는 개발자

0개의 댓글