Logo

[GraphQL] Apollo Client로 React 앱 개발하기

Apollo Client는 GrpahQL API를 호출하기 위해 사용되는 라이브러리입니다. 이번 포스팅에서는 React 앱에서 Apollo Client를 사용하여 GraphQL API를 호출하는 방법에 대해서 알아보겠습니다.

사실, GraphQL API를 호출할 때, 반드시 Apollo Client와 같은 전용 클라이언트가 필요한 것은 아닙니다. GraphQL API를 별다른 라이브러리 없이 최대한 간단하게 호출하는 방법에 대해서는 아래에 따로 포스팅해놓았으니 참고바랍니다.

그리고, React 없이 순수하게 Apollo Client만을 사용하는 방법은 아래 포스팅를 참고바랍니다.

패키지 설치

리액트 프로젝트에 Apollo Client를 사용하기 위해서 다음 패키지 세개를 설치합니다.

$ npm i apollo-boost graphql react-apollo

참고로 apollo-boost는 Apollo에서 제공하는 GraphQL 클라이언트 패키지이며, graphql은 Facebook에 정의한 GraphQL 스팩을 JavaScript 언어로 구현한 패키지입니다. Apollo Server든 Apollo Client든 내부적으로는 모두 graphql 패키지에 의존하고 있기 때문에 반드시 함께 설치를 해줘야 합니다. react-apollo는 React 앱에 Apollo Client를 연결(Integration)해주는 패키지입니다.

Apollo Client 생성

먼저, Apollo Client를 생성해야 하는데, 이 때 호출할 GraphQL API의 접속 정보를 설정해줘야 합니다. apollo-boost 패키지에서 임포트한 ApolloClient 생성자 함수의 인자로 uri 속성이 포함된 설정 객체를 넘기면 됩니다. 여기서는 대륙/국가 데이터를 제공하는 공개된 GraphQL API를 사용하겠습니다.

import ApolloClient from "apollo-boost";

const client = new ApolloClient({
  uri: "https://countries.trevorblades.com",
});

React에 Apollo Client 연결

다음으로, 위에서 생성한 ApolloClient 객체를 React에 연결해줘야 합니다. 앱 내에서 특정 React 컴포넌트만 GraphQL API 호출이 필요한 경우가 아닌 이상, 모든 React 컴포넌트에서 ApolloClient를 사용하도록 설정하는 것이 일반적입니다. 예를 들어, create-react-app으로 생성한 React 앱이라면 App.js 파일에서 이 작업을 해야합니다.

react-apollo 패키지에서 임포트한 ApolloProvider 컴포넌트로 앱의 최상위 컴포넌트를 감싸줍니다. 이 때, client prop에 위에서 생성한 ApolloClient 객체를 넘겨줘야 합니다. 이렇게 설정을 해주면, 앱 내의 모든 컴포넌트에서 GraphQL API 연동이 가능해집니다.

import React from "react";
import { ApolloProvider } from "react-apollo";
import Continents from "./Continents";

function App() {
  return (
    <ApolloProvider client={client}>
      <h1>React + Apollo Client</h1>
      <Continents />
    </ApolloProvider>
  );
}

GraphQL API 호출

React에서 Apollo Client를 사용해서 좀 더 간편하게 GraphQL API를 호출할 수 있도록 react-apollo 패키지는 QueryMutation 컴포넌트를 제공합니다. 본 포스팅에서 사용하는 GraphQL API는 mutation은 제공하지 않기 때문에, query를 호출하는 예제 컴포넌트만 작성해보겠습니다.

먼저, apollo-boost 패키지에서 제공하는 gql이라는 template literal tag를 사용해서 일반 자바스크립트 문자열을 GraphQL 구문으로 바꿔줍니다. 그 다음, 이 GraphQL 구문을 react-apollo 패키지에서 임포트 한 Query 컴포넌트의 query prop으로 넘김니다. 그리고 이 Query 컴포넌트는 GraphQL API 호출 상태에 따라 랜더링할 내용을 리턴하는 함수를 자식으로 가져야합니다.

REST API를 호출할 때 비동기 처리를 하는 것과 마찬가지로 GraphQL API 호출할 때도, GraphQL 서버로 부터 데이터를 응답 받는데 시간이 걸리기 마련입니다. 이렇게 서버로 부터 응답을 기다리는 동안 Query 컴포넌트는 loading 파라미터에 ture 값을 할당해줍니다. 따라서 사용자에게 응답 데이터가 뿌려지기 전까지 로딩 중이라는 메시지나 spinner 애니메이션 등을 표시해 줄 수 있습니다. error 파리미터는 GraphQL API 호출이 실패된 경우, 오류 데이터가 할당되며, data 파라미터는 GraphQL API 호출이 성공한 경우, 정상 데이터가 할당됩니다.

import React from "react";
import { gql } from "apollo-boost";
import { Query } from "react-apollo";

const GET_CONTINENTS = gql`
  query {
    continents {
      code
      name
    }
  }
`;

function Continents() {
  return (
    <>
      <h2>Continents</h2>
      <Query query={GET_CONTINENTS}>
        {({ loading, error, data }) => {
          if (loading) return <p>Loading...</p>;
          if (error) return <p>Error!(</p>;
          return (
            <ul>
              {data.continents.map(({ code, name }) => (
                <li key={code}>{name}</li>
              ))}
            </ul>
          );
        }}
      </Query>
    </>
  );
}

export default Continents;

전체 코드

마치면서

이상으로 Apollo Client를 이용해서 React 앱에서 GraphQL API를 호출하눈 방법에 대해서 알아보았습니다. 최근에 Apollo Hooks가 Apollo Client에 추가되어서, React 앱에서 GraphQL API를 호출하는 더 나은 방법이 생겼습니다. 이 부분에 대해서는 아래 포스팅에 별도로 다뤘으니 참고 바라겠습니다.