apollo/client 기억하기

이경준·2021년 3월 7일
1

GraphQL이란?

GraphQL은 기존에 많이 사용되는 REST API의 한계점을 극복하고자 나온 통신규약이다. REST API같은 경우 데이터를 조회할시 복잡한 서비스일수록 Over-Fetching이된다는 단점이 있지만 GraphQL은 원하는 데이터만 가져올수 있으며, 원하는데이터를 모두 한번에 가져올수 있다는 장점도 있다.

Apollo/Client?

apollo는 graphql의 클라이언트 라이브러리이다.

react환경에서 graphql을 사용할시 상태관리 라이브러리로 강력한 redux를 쓰지 않고도 상태관리를 할 수 있다.

전송받은 데이터를 자동으로 캐싱하여 클라이언트의 반복 요청을 줄이고 서비스이용자에게 더 나은 사용자 경험을 제공한다.

1. provider 연결하기

import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'https://...',
  cache: new InMemoryCache()
});

return (
      <ApolloProvider client={client}>
        <Start />
      </ApolloProvider>
  );

redux와 같이 provider문법으로 감싸면 감싸진 전역에서 데이터를 가져올수있다.

2. Apollo Client Dev Tool 설치

1.크롬에서 Apollo Client Developer Tools라고 친후 다운 받으면 개발자 도구에서 캐시상태와 정보를 즉시 확인 가능하다.

3. useQuery 사용해보기

import { gql, useQuery } from "@apollo/client"

const FETCH_QUERY = gql`
  query getUser{
    users {
      user {
        id
        image
      }
    }
  }
`

const { loading, error, data } = useQuery(FETCH_QUERY)

1.gql과 useQuery함수를 사용하여 서버에서 데이터를 전송받을수 있다.
2.gql에는 받고싶은 데이터를 쿼리문서로 구문 분석하여 useQuery로 전달하여야 한다.
3.그렇게 전달하면 loading,error,data상태를 받는데 상태에따라 ui를 구현할수있다.
4.그렇게 데이터를 가져올때마다 local로 캐시하여 후속실행이 빠르다는 장점이있다.

4. 아이디에맞는 user만 받아오기

import { gql, useQuery } from "@apollo/client";

const FETCH_QUERY = gql`
  query getUser {
    users {
      user {
        id
        image
      }
    }
  }
`;

const { loading, error, data } = useQuery(FETCH_QUERY);

variables로 조건에 맞는 데이터를 함께보내서 원하는 데이터만 받을수 있다.

5. 시간간격마다 데이터 받아오기

import { gql, useQuery } from "@apollo/client";

const FETCH_USER = gql`
  query getUser($id: ID!) {
    getUser(id: $id) {
      user {
        image
        content
      }
    }
  }
`;

const { loading, error, data, refetch } = useQuery(FETCH_USER, {
  variables: { id: 1 },
  pollInterval: 500, //*
});

1.pollInterval을 사용하여 0.5초마다 데이터를 전송받을수있게 설정할수있다.
2.refetch를 사용하면 버튼을 눌렀을때(?) 다시한번 데이터를 받아올수 있는 ui를 구현가능하다.

6. 수동으로 쿼리 실행하기

import { gql, useLazyQuery } from "@apollo/client";

const FETCH_USER = gql`
  query getUser($id: ID!) {
    getUser(id: $id) {
      user {
        image
        content
      }
    }
  }
`;

const [getUser, { loading, error, data }] = useLazyQuery(FETCH_USER);

return (
  <>
    {data.content}
    <button onClick={() => getUser({ variables: { id: 1 } })}> 버튼 </button>
  </>
);

useLazyQuery를 사용하여 수동적으로 쿼리를 받아올수있다.
variables는 함수의 파라미터로 주입해주면 된다.

7. useMutation 사용하기 (update)

import { gql, useMutation } from "@apollo/client";

const CREATE_USER = gql`
  mutation createUser($body: String!) {
    createUser(body: $body) {
      id
    }
  }
`;

const [addUser, { data }] = useMutation(CREATE_USER);

return (
  <>
    <button onClick={() => addUser({ variables: { body: 바디 } })}>버튼</button>
  </>
);

useMutation은 데이터를 가져오는것 외에 update방식으로 데이터를 전송하고전송받을때 사용 가능하다.

8. 쿼리 update시 또는 error시 ui구현하기

import { gql, useMutation } from "@apollo/client";

const CREATE_USER = gql`
  mutation createUser($body: String!) {
    createUser(body: $body) {
      id
    }
  }
`;

const [addUser, { data }] = useMutation(CREATE_USER,{
  variables: { body: 바디 },
  update(){
    console.log('다음페이지로이동')
  },
  onError(){
    console.log('에러페이지로이동 ')
  }
});

return (
  <>
    <button onClick={() => addUser({ variables: { body: 바디 } })}>버튼</button>
  </>
);

update함수와 onError함수를 이용하여 이후의 ui를 구현할수있다.

9. 데이터 업데이트 시키기

apollo로 받아온 데이터는 redux상태관리와 같이 data가 바로 업데이트되지 않는다. 업데이트하기 위해서는 따로 문법을 작성해주어야 한다.

const [createPost, { error }] = useMutation(CREATE_POST_MUTATION, {
    variables: values,
    update(proxy, result) {
      const data = proxy.readQuery({ //*
        query: FETCH_POSTS_QUERY,
      });
      const newData = [result.data.createPost, ...data.getPosts];
      proxy.writeQuery({  //*
        query: FETCH_POSTS_QUERY,
        data: { ...data, getPosts: newData },
      });
      values.body = "";
    },
  });

update함수 안에 readQuery를 사용하여 query를 입력하면 조건에 맞는 data를 가져올수 있으며 writeQuery를 이용하여 데이터를 변경시켜주면 update될때마다 query에 맞는 데이터가 바로 업데이트 된다.

10. 데이터 전송할때마다 토큰 함께 전송하기

import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";

const httpLink = createHttpLink({
  uri: "http://localhost:5000",
});

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem("jwtToken");

  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    },
  };
});

export const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});

setContext에서 토큰을 가져온다음 return하는 방식으로 데이터를 전송할때마다 토큰이 전달될수있게 구현된다.

profile
내가 기억하기위한 블로그

0개의 댓글