GraphQL Client 적용하기

Imnottired·2023년 2월 21일
0

Apollo Client는 상태관리 라이브러리다.
GraphQL api에서 데이터를 fetch 해오는 것을 가능하게 해주고
어플리케이션에서 로컬로 상태 관리할 수도 있게 해준다.
서버에 있는 데이터를 가지고 오는 것, 로컬에 있는 데이터를 관리하는 것
그리고 이 둘을 동기화 할 수 있다.

npx create-react-app movieql-client

$ yarn add @apollo/client graphql react-router-dom@6

세팅 완료 후

필요없는 파일들 지워준다.

기본 셋팅으로 2가지 파일을 만든 뒤 라우터 셋팅


const { ApolloClient, InMemoryCache } = require("@apollo/client");

const client = new ApolloClient({
  uri: "http://localhost:4000/", 
  cache: new InMemoryCache(),
});

export default client;

client. js 작성한다
uri: "http://localhost:4000/"의 의미는 GraphQL 서버는 localhost:4000에서 돌아가고 있다.

cache: new InMemoryCache(),
cache strategy인데 캐싱에 대해서 다루는 거 같다.

그다음에 client가 잘 돌아가는 지 확인하기 위해서
훅을 사용할 것이다.

client.query({
query : gql`
{ 
	allMovies {
    	title
    }
    }
`
}).then(data=> console.log(data));

이후에 index.js에 추가해주면

결과가 잘나온다 😆


import React from "react";
import ReactDOM from "react-dom/client";
import client from "./routes/client.";
import App from "./App";
import { ApolloProvider } from "@apollo/client";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>
);

index.js를 아폴로 감싸주고 client를 내려준다.

export default function Movies() {
  const client = useApolloClient();
  useEffect(() => {
    client
      .query({
        query: gql`
          {
            allMovies {
              title
            }
          }
        `,
      })
      .then((res) => console.log(res));
  },[client]);
  return <div>hi</div>;
}

(모든 단계를 적는 명령형, 우리가 무엇을 원하는지 적는다.)
Provider는 애플리케이션 안의 모두가 이 client에 접근할 수 있게 해준다.

아까와 동일한 값이 나온다.
usestate를 이용하여 값을 꺼내줄 수 있지만, 매번 이렇게 쓰는건 지저분하다
매력적이고 멋지게 쓰기 위해서는 Hook을 사용해야한다.

const ALL_MOVIES = gql`
  query getMovies{
    allMovies {
      title
      id
    }
  }
`;

query getMovies <-써도 되고 안써도된다.
구분하거나 의미를 두기위해 쓴다.


바로 useQuery 이용하여 훅을 만든다.
useQuery는 여러 결과들을 전달해주는데

    client: ApolloClient<any>;
    observable: ObservableQuery<TData, TVariables>;
    data: TData | undefined;
    previousData?: TData;
    error?: ApolloError;
    loading: boolean;
    networkStatus: NetworkStatus;
    called: boolean;

이러한 내용들이 결과로 온다.
const result = useQuery(ALL_MOVIES);
result를 콘솔로그를 사용해 불러주면


결과값이 이렇게 온다.
loading이 true로 되어있는데 이는 아직 데이터를 받지 못한 상태이다.
(React Query와 유사하다)


false로 변하니 데이터값을 받아왔다.
React Query와 같은 방법으로
const {data, loading] = useQuery(ALL_MOVIES); 로 선언했다.

선언형 코드를 쓰게해주기때문에 매우 깔금했다.
(선언형 코드는 설명하기위한 코드만 적는 것을 말한다.
반면에 명령형:imperative 은 모든 단계의 코드를 적고 무엇을 원하는지 작성한다.)


export default function Movies() {
  const { data, loading, error } = useQuery(ALL_MOVIES);
  if (loading) {
    return <h1>loading</h1>;
  }
  if (error) {
    return <h1>Could not fetch :(</h1>;
  }
  return (
    <div>
      {data.allMovies.map((movie) => (
        <li key={movie.id}>{movie.title}</li>
      ))}
    </div>
  );
}

로 완성한다.

useQuery로 매우 심플하게 되었다.

const ALL_MOVIES = gql`
  query getMovies {
    allMovies {
      title
      id
    }
    allTweets {
      id
      text
      author {
        fullName
      }
    }
  }
`;

아폴로 사용한거와 동이할게 쿼리를 요청하여 받아올 수 있다.


결과도 이쁘게 잘나왔다.

코드가 매우 심플해져서 만족한다.

그다음 Link를 이용해

 return (
    <div>
      <h1>Movies</h1>
      {data.allMovies.map((movie) => (
        <li key={movie.id}>
          <Link to={`/movies/${movie.id}`}>{movie.title}</Link>
        </li>
      ))}
    </div>
  );

적용시킨다.
그러면 param에 id값이 담긴다.


위 그림처럼 Variables 을 React에서 사용하려면 useQuery 훅을 사용해야한다.

const GET_MOVIE = gql`
  query getMovie($movieId: String!) {
    movie(id: $movieId) {
      id
      title
    }
  }
`;

export default function Movie() {
  const { id } = useParams();
  const { data, loading } = useQuery(GET_MOVIE, {
    variables: {
      movieId: id,
    },
  });

  if (loading) {
    return <h1>Fetching movie...</h1>;
  }
  console.log(data, loading);
  return <div>{data.movie.title}</div>;
}

두번째 파라미터에 객체를 선언한 뒤 Variables라고 선언해준다.
$movieId와 movieId는 이름을 통일해야한다.

new InMemoryCache()에 의해 한번 들어갔던 곳을 다시 들어가면 로딩을 하지않는다.

왜냐하면 캐싱 되었기 때문에 바로 title을 보여준다.


이 확장을 사용하면 캐시를 더 쉽게 확인할 수 있다.


이를 통해 빠르게 GraphQL에 대하여 확인할 수 있다.


캐싱된 정보도 확인이 가능하다.

이렇게 아폴로의 캐싱 기능도 알아보았다.
리액트 쿼리와 비슷하다는 느낌을 받았다.

profile
새로운 것을 배우는 것보다 정리하는 것이 중요하다.

0개의 댓글