GraphQL 5 - Client
이전에 만든 GraphQL 서버로의 요청은 ApolloClient를 통해 가능하다. apollo공식문서 와 강의를 참고하여 간단한 클라이언트를 구현해보자.
1. 세팅
npx create-react-app tour-client
먼저 React 프로젝트를 생성한다.
npm install @apollo/client graphql
@apollo/client와 graphql을 설치한다. 사실 몇 개월 전만 해도 apollo-boost를 사용했었는데 공식문서에 의하면 지원하지 않는 몇 가지 고급 기능이 있으므로 ApolloClient를 사용하라는 문구를 볼 수 있다. 또한 @apollo/react-hooks, react-apollo도 @apollo/client에 통합되었다고 한다.
2. Client 생성
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000',
cache: new InMemoryCache()
});
export default client;
3. React와 연결
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App'; //GraphQL 데이터를 사용할 React 컴포넌트
import client from "./apollo" //2에서 생성한 Client
import { ApolloProvider } from "@apollo/client"
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
@apollo/client의 APolloProvider는 ApolloProvider라는 리액트 컴포넌트처럼 사용하면 된다. 다만 리액트의 데이터는 위에서 아래방향으로 흐르므로 GraphQL의 데이터가 필요한 다른 리액트 컴포넌트를 감싸는 방식이어야 한다.
4. Query
import React from "react";
import { gql, useQuery } from '@apollo/client'
const GET_SIGHTS = gql`
{
sights(city:1, keyword:"공원") {
title
addr1
addr2
homepage
contentid
}
}
`;
export default () => {
const { loading, error, data } = useQuery(GET_SIGHTS);
if (loading) {
return "now loading";
}
if (data && data.sights) {
return data.sights.map(sight => <div key={sight.contentid}>{sight.title}</div>);
}
if (error) {
return "error!!";
}
};
이제 데이터가 필요한 컴포넌트에서 쿼리를 작성하고 이를 UI에 렌더링해보자. 쿼리는 @apollo/client의 gql를 이용하여 작성한 후 요청 결과는 useQuery를 통해 받을 수 있다. loading은 요청 결과가 도착하였는지를 판단하는 불리언 값으로 서버로부터 응답이 오면 false로 변경된다.
const GET_SIGHT = gql`
query Sight($id: Int!) {
sight(id: $id) {
homepage
title
}
}
`;
export default () => {
const { id } = useParams();
const { loading, data, error } = useQuery(GET_SIGHT, {
variables: {
id: Number(id)
},
});
return "Detail";
};
쿼리에 자바스크립트 변수가 포함되는 경우엔 위와 같이 쿼리의 이름을 적고 $ 키워드를 사용하여야 한다. 또한 useQuery를 사용할 때 쿼리와 함께 변수를 전달해주어야 한다. 위 코드에서는 id 부분이 자바스크립트 변수이므로 $키워드를 사용하였다. 또한 useQuery의 두 번째 인자 는 { [key : string] : any} 와 같은 형식이므로 String이 아닌 타입을 사용해야하는 경우 위와 같이 형변환을 해주어야 한다.
참고 사이트: