[GraphQL] Next.js 15에 GraphQL(Apollo Client) 적용하기

Woonil·2025년 9월 8일
0

GraphQL

목록 보기
1/1

Next.js 15 버전에서 apollo client를 적용하는 과정에 대해 설명하는 글이다.

처음 Next.js 15로 만든 프로젝트에 apollo client를 적용할 때, 이 라이브러리가 존재하지 않았다. 기존 Apollo GraphQL 라이브러리에 나와있던 experimental 버전을 사용하다가 아래 에러를 겪고 결국 해결하지 못해 잠시 접어두고 있었다. 프로젝트를 계속 진행하다가 @apollo/client-integration-nextjs 라이브러리가 새로 릴리즈된 것을 알게 되었고, 이를 적용함으로써 이전의 문제를 해결할 수 있었다.

Error: (0 , _apollo_client_integration_nextjsWEBPACK_IMPORTED_MODULE_2.registerApolloClient) is not a function

아래는 이 패키지가 나온 배경과 특징에 관해 설명한 글이다. 간단히 요약하자면 이 패키지는 ‘Next.js에서 Apollo Client를 RSC와 SSR 각각의 상황에 맞게 잘 통합해 주는 도구’로써 사용될 수 있다는 것이다.

블로그 - @apollo/client-integration-nextjs Officially Released | Apollo GraphQL Blog
공식문서 - @apollo/client-integration-nextjs

이제 공식문서를 따라 초기 세팅을 진행해보자.

  1. 설치: 이 라이브러리는 @apollo/client에 의존한다.
    npm install @apollo/client@latest @apollo/client-integration-nextjs
  2. 서버 컴포넌트 관련 ApolloClient 객체 초기화: 서버 컴포넌트에서 graphql 요청을 처리하기 위한 설정이다. query()는 Promise 객체를 반환하기 때문에 사용하는 쪽에서는 비동기 처리를 위해 async/await 키워드를 사용해야 한다. 이 Promise 객체는 loadingerrordata 프로퍼티를 갖는 객체로 resolve된다.
    import { HttpLink } from "@apollo/client";
    import {
      registerApolloClient,
      ApolloClient,
      InMemoryCache,
    } from "@apollo/client-integration-nextjs";
    
    export const { getClient, query, PreloadQuery } = registerApolloClient(() => {
      return new ApolloClient({
        cache: new InMemoryCache(),
        link: new HttpLink({
          // graphql api 엔드포인트에 대한 절대 경로
          uri: "http://example.com/api/graphql",
          fetchOptions: {
          },
        }),
      });
    });
  1. 클라이언트 컴포넌트 관련 ApolloClient 객체 초기화

    클라이언트 컴포넌트에서 graphql 요청을 처리하기 위한 설정이다. 사용하는 쪽에서는 useSuspenseQuery 를 사용하여 React의 Suspense와 조합할 수 있다.

    "use client";
    
    import { HttpLink } from "@apollo/client";
    import {
      ApolloNextAppProvider,
      ApolloClient,
      InMemoryCache,
    } from "@apollo/client-integration-nextjs";
    
    // have a function to create a client for you
    function makeClient() {
      const httpLink = new HttpLink({
        // graphql api 엔드포인트에 대한 절대 경로
        uri: "https://example.com/api/graphql",
        fetchOptions: {
        },
      });
    
      // use the `ApolloClient` from "@apollo/client-integration-nextjs"
      return new ApolloClient({
        // use the `InMemoryCache` from "@apollo/client-integration-nextjs"
        cache: new InMemoryCache(),
        link: httpLink,
      });
    }
    
    // 루트 레이아웃에서 사용될 래퍼
    export function ApolloWrapper({ children }: React.PropsWithChildren) {
      return (
        <ApolloNextAppProvider makeClient={makeClient}>
          {children}
        </ApolloNextAppProvider>
      );
    }
    // 루트 레이아웃에 적용한다.
    import type { Metadata } from 'next';
    import './globals.css';
    import Link from 'next/link';
    import MSWProvider from '@/applications/msw-provider';
    import { ApolloWrapper } from '@/applications/apollo-wrapper';
    
    export const metadata: Metadata = {
    };
    
    export default function RootLayout({
      children,
      modal,
    }: Readonly<{
      children: React.ReactNode;
      modal: React.ReactNode;
    }>) {
      const isMockingEnabled = process.env.NEXT_PUBLIC_API_MOCKING === 'enabled';
      return (
        <html lang="en">
          <ApolloWrapper>
            <body>
            </body>
          </ApolloWrapper>
        </html>
      );
    }

ApolloClient의 link와 cache는 필수 옵션이다.

😎실습

실습 환경은 MSW로 응답을 모킹하고 있으며, 엔드포인트는 MSW의 목 서버로 지정되어 있음을 미리 알린다.

클라이언트 컴포넌트에서 GraphQL 요청하기

SuspenseuseSuspenseQuery 훅을 사용하여 요청을 수행해본다.

서버 컴포넌트에서 GraphQL 요청하기

MSW의 핸들러 상에 graphql 요청에 대한 응답 핸들러가 아래와 같이 정의된 상태이다.

이전에 서버 컴포넌트를 위해 선언했던 apollo-client의 query를 사용하여 실제 쿼리를 수행해본다. query 에는 gql 템플릿 리터럴 태그로 감싼 쿼리문을 할당한다.

서버 액션에서 GraphQL 사용하기

서버 사이드에서 일어나는 Next의 서버 액션 특성상 Apollo Client가 제공하는 클라이언트 동작을 수행하는 mutation 코드를 작성할 수 없다. 하지만, GraphQL은 기본적으로 HTTP 기반으로 동작하기 때문에, 별도의 라이브러리 없이 fetch 메서드를 통해서도 HTTP 요청을 보낼 수 있다.

참고자료

npm 공식문서
Nextjs Graphql mutation query using App router
Daleseo 블로그 - [GraphQL] Apollo Client 사용법
Is it possible to make GraphQL mutations into server side calls with NextJs App Router (v14)?

profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글