이번에는 Apollo Client를 구현해보겠습니다!
통신을 해보는 것이 목적이기에 Client 셋팅 방법과, 어떤식으로 통신이 이루어지는지 전체적인 그림을 그려보겠습니다.
컴포넌트 구조와 리액트 대해서는 자세하게 다루지않습니다.
(저는 Apollo + React를 사용하였지만 Vue로도 graphQL Client를 만들 수 있습니다!)
Setting Apollo Client
npm install @apollo/client graphql
명령어를 입력하여 아폴로 클라이언트모듈을 설치합니다.
app.js에서 ApolloClient 모듈을 import 해줍니다.
import { ApolloProvider } from '@apollo/client';
import { ApolloClient, InMemoryCache } from '@apollo/client'
그 다음 ApolloClient 객체를 생성합니다.
client: graphQL서버로 정보를 주고받을 역할을 하는 ApolloClient객체
uri: GraphQL 서버의 주소
cache, InMemoryCach(): 그래프큐엘 클라이언트가 한 번 받아온 정보들을 필요 이상으로 다시 요청하지 않도록 캐쉬를 관리하는 역할
GraphQL이 클라이언트에서 사용될 수 있도록 ApolloProvider로 최상위 컴포넌트를 감싸줍니다.
그런데 이렇게만 하니까
'ApolloProvider was not passed a client instance. Make sure you pass in your client via the "client" prop.'라는 에러가 떳습니다..! 왜냐하면 위에서 생성해준 ApolloClient객체를 전달해주지 않아서 그렇습니다!
ApolloProvider에 ApolloClient객체를 생성한 client를 전달해줍니다.
🎉그럼 이제 하위에 있는 컴포넌트들에서 아폴로 클라이언트를 사용해서 서버로부터 데이터를 불러오거나 전송할 수 있게 되었습니다!
(컴포넌트들은 main tag를 대체해서 넣었습니다.)
graphQL Server로부터 목록 받아오기 : Query
쿼리로 받아오기 위해서 필요한 모듈을 import 해주는 것으로 시작해봅시다.
import { useQuery, gql } from "@apollo/client";
import와 component 사이에 받아 올 쿼리를 gql을 이용하여서 그래프큐엘 서버에 보낼 요청객체를 만들어 주었습니다.
const GET_ROLES = gql`
query GetRoles {
roles {
id
}
}
`;
랜더링 될 컨텐츠의 id를 저장할 state지정하였습니다.
const [contentId, setContentId] = useState('');
그리고 contentId에 , GraphQL로부터 데이터를 받아와 목록을 렌더링하도록하였습니다. (코드 생략)
우리가 요청한 값들이 잘 반환되는지 확인해볼까요?
개발자도구에서 > 로컬호스트 > preview를 눌러보면, 요청한 값들이 반환된 것을 알 수 있습니다.
여기에 requirment 정보도 같이 요청해볼까요?
앞에서 요청했던 GET_RULES객체 안에 그냥 추가해주면 됩니다.
다시 requirement가 같이 잘 들어왔는지 개발자도구 > 로컬호스트 > preview 를 확인해 보겠습니다.
짠~ requirement 도 같이 응답이 왔습니다!
정말 간단하게 원하는 정보만 깔끔하게 받아올 수 있는것을 알 수 있습니다.
useQuery로 loading, error, data 처리하기
그런데 쿼리를 받아올 때 혹시 로딩 중이거나 에러가 뜨면 어떻게할까요?
그럴때는 useQuery를 이용해서 처리해 줄 수 있습니다.
요청을 받아오는 동안 인터넷이 늦으면 loading, 오류가 발생하면 error를 반환해주고, data가 정상적으로 들어오면 return 된 곳을 반환해줍니다.
아래 코드를 보며 더 자세하게 알아보겠습니다.
이렇게 하면 컴포넌트가 실행될 때 useQuery가 실행됩니다.
useQuery 실행 인자에 gql태그를 넣어 요청하면(저희는 상수로 만들어서 GET_ROLES를 넣어주었습니다.) apollo-server resolver를 실행합니다.
useQuery hook은 resolver에서 반환하는 결과들 중에서 gql태그로 받아올 값을 선택할 수 있는데,
resolver가 실행중일 때는 loading은 true상태입니다.
resolver에서 error가 발생하면 error, 성공적으로 값을 받아오면 data에 값이 담김니다.
따라서 useQuery를 이용해서 loading, error, sucess에 대한 대응을 간편하게 할 수 있습니다.
결과 화면을 비교하며 제대로 작동했는지 보겠습니다.
👍 먼저 데이터가 정상적으로 들어왔을때 입니다.
👎 그리고 아래는 제가 임의로 uri를 이상하게 작성하여 에러가 나오게 하였습니다.
(그리고 쿼리문을 resolver에 맞지 않게 작성해도 에러가 나옵니다~!)
지금까지 Apollo Client를 만들고, graphQL 서버에서 쿼리를 이용하여 data를 불러오는 작업을 해보았습니다.
사실 GraphQL 아폴로 서버를 만들면서 playground를 통해 쿼리, 뮤테이션이 어떻게 주고받는지 이미 해보았습니다.
playground에서 쿼리, 뮤테이션, 인자받기 등의 연습을 한 것처럼 gql을 이용하여 상황에 맞게 객체를 만들어 보내주면 됩니다.
물론 이렇게 요청할 객체를 전달할 때, 그래프큐엘 서버에 이와 같은 요청을 스키마와 resolver를 짜놓았기에 가능한 것입니다.😸👍