ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [GraphQL] GraphQL 시작하기 (2)
    프론트엔드 2020. 12. 12. 11:26
    728x90

    이번 포스트에선 React앱에서 GraphQL 클라이언트를 생성하는 방법에 대해 알아보겠습니다.

     

    패키지 설치

    $ npm install @apollo/client

     

    ✔ 클라이언트 생성

      아래와 같이 ApolloClient 인스턴스를 초기화합니다. ApolloClient 생성자는 두 개의 인자를 받습니다.

      첫번째는 'link'로 이전 포스트에서 세팅한 GraphQL 서버의 URL을 지정하면됩니다.

      두번째는 'cache'로 가장 많이 사용되는 InMomoryCache를 사용했습니다.

      다만 아래의 코드에는 초기화 과정에 토큰을 통해 인증하는 코드가 추가되어, 해당 코드 신경쓰지 마시고 URL만 넘기면 됩니다.

      ApolloProvider로 기존의 React App을 래핑하면 컨텍스트를 통해 각각의 모든 컴포넌트에서 액세스 가능해집니다. 

    import React from 'react';
    import App from './App';
    import ApolloClient from 'apollo-client';
    import { InMemoryCache } from 'apollo-cache-inmemory';
    import { createHttpLink } from 'apollo-link-http';
    import { ApolloProvider } from '@apollo/react-hooks';
    import { setContext } from 'apollo-link-context';
    
    const httpLink = createHttpLink({
      uri: 'http://localhost:5000'
    });
    
    const authLink = setContext(() => {
      const token = localStorage.getItem('jwtToken');
      return {
        headers: {
          Authorization: token ? `Bearer ${token}` : ''
        }
      };
    });
    
    const client = new ApolloClient({
      link: authLink.concat(httpLink),
      cache: new InMemoryCache()
    });
    
    export default (
      <ApolloProvider client={client}>
        <App />
      </ApolloProvider>
    );

    ✔ useQuery

      위에서 GraphQL로 데이터를 요청할 준비를 하였으니 데이터를 쉽게 요청할 수 있는 hooks에 대해 알아보겠습니다.

      useQuery는 데이터를 UI와 공유하는 hooks입니다. gql쿼리를 useQuery에 전달하면, 구성요소가 랜더링되고 그 결과로 

      loading, error, data 등의 속성이 반환됩니다.

      const {
        loading,
        data: { getPosts: posts } = {}
      } = useQuery(FETCH_POSTS_QUERY);
      
      const FETCH_POSTS_QUERY = gql`
      {
        getPosts {
          id
          body
          createdAt
          username
          likeCount
          likes {
            username
          }
          commentCount
          comments {
            id
            username
            createdAt
            body
          }
        }
      }
    `;

      ✔ useMutation

      useMutation은 데이터 변경하는 hooks입니다. gql쿼리를 useMutation에 전달하면, 구성요소가 랜더링되고 그 결과로 

      useMutation 함수를 포함한 속성이 반환됩니다. 반환된 useMutation 함수로 mutate 함수를 실행합니다.

      const [createPost, { error }] = useMutation(CREATE_POST_MUTATION, {
        variables: values,
      });
    
      function createPostCallback() {
        createPost();
      }
      
      const CREATE_POST_MUTATION = gql`
      mutation createPost($body: String!) {
        createPost(body: $body) {
          id
          body
          createdAt
          username
          likes {
            id
            username
            createdAt
          }
          likeCount
          comments {
            id
            body
            username
            createdAt
          }
          commentCount
        }
      }
    `;

    ✔ 캐시 업데이트

      useMutation()를 사용할 경우, 변경사항이 화면에 바로 나타나지 않고 새로고침 후 반영되는걸 확인하실 수 있을 겁니다.

      이는 useMutation() 호출을 통해 추가된 데이터가 캐시에 반영되지 않아서 생기는 문제입니다.

      

      추가된 데이터는 사용자가 직접 갱신해줘야 합니다. 이때 useMutation()의 update() 옵션을 활용합니다.

      update()는 두 가지 인수 cache와 mutationResult를 받게 됩니다. 

    export declare type MutationUpdaterFn<T = {
        [key: string]: any;
    }> = (cache: ApolloCache<T>, mutationResult: FetchResult<T>) => void;

      readQuery()  : 캐시 위에서 직접 GraphQL 쿼리를 실행합니다. 서버에서 실행한 것과 동일하게 반환됩니다.

      writeQuery() : 사용자가 지정한 데이터를 GraphQL 형태로 캐시에 씁니다.

      const [createPost, { error }] = useMutation(CREATE_POST_MUTATION, {
        variables: values,
        // 캐시 업데이트
        update(proxy, result) { // proxy: cache, result: CREATE_POST_MUTATION 결과
          const data = proxy.readQuery({
            query: FETCH_POSTS_QUERY
          }); // 캐시에서의 FETCH_POSTS_QUERY 결과
    
          data.getPosts = [result.data.createPost, ...data.getPosts];
          proxy.writeQuery({ query: FETCH_POSTS_QUERY, data });
          // CREATE_POST_MUTATION 결과 + 캐시에서의 FETCH_POSTS_QUERY 결과로 캐시 데이터 업데이트
          values.body = '';
        }
      });
    

     

      추가적으로 Apollo 캐시를 확인하시려면 아래의 크롬 확장도구인 Apollo Dev Tool을 설치하시기 바랍니다.

    Apollo Dev Tool

    ✔ 마무리

      GraphQL 클라이언트 생성 및 hooks를 통해 데이터를 서버로 부터 받아오는 방법에 대해 알아보겠습니다.

      이번 포스트, 앞서의 포스트만 참고하셔도 충분히 원하시는 서버 및 클라이언트 구축 가능하니 많은 도움이 되었으면 좋겠습니다.

Designed by Tistory.