[GraphQL] Apollo Client 사용법

GraphQL API를 호출할 때 사용하는 클라이언트 라이브러리인 Apollo Client에 대해서 알아보겠습니다.

기본적으로 HTTP 기반으로 동작하는 GraphQL API를 호출할 때 반드시 Apollo Client와 같은 전용 클라이언트 라이브러리가 필요한 것은 아닙니다.
GraphQL API를 별다른 라이브러리 없이 최대한 간단하게 호출하는 방법에 대해서 관련 포스트를 참고바라겠습니다.

패키지 설치

프로젝트에 Apollo Client를 사용할 때 필요한 5개의 패키지를 설치합니다.

1
$ npm i apollo-client apollo-cache-inmemory apollo-link-http graphql graphql-tag
  • pacakge.json
1
2
3
4
5
6
7
"dependencies": {
"apollo-cache-inmemory": "1.6.3",
"apollo-client": "2.6.4",
"apollo-link-http": "1.5.15",
"graphql": "14.4.2",
"graphql-tag": "2.10.1"
}

이 중, apollo-clientapollo-cache-inmemory, apollo-link-http는 Apollo에서 제공하는 GraphQL 클라이언트 관련 라이브러리이며,
graphql은 Facebook에 정의한 GraphQL 스팩을 JavaScript 언어로 구현체이고, graphql-tag는 GraphQL 쿼리를 파싱해주는 템플릿 리터럴 태그입니다.

패키지 임포트

위에서 설치한 패키지로 부터 ApolloClient, InMemoryCache, createHttpLink, gql을 임포트 합니다.

1
2
3
4
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { createHttpLink } from "apollo-link-http";
import gql from "graphql-tag";

클라이언트 생성

Apollo Client를 사용하려면 먼저 ApolloClient 객체를 생성해야합니다.
ApolloClient 생성자는 옵션 객체를 인자로 받는데, 이 객체의 linkcache는 필수 옵션입니다.

1
2
3
4
const client = new ApolloClient({
link: createHttpLink({ uri: "https://countries.trevorblades.com" }),
cache: new InMemoryCache()
});

link 옵션에는 ApolloLink 객체를 넘거야 하고, cache 옵션에는 ApolloCache 객체를 넘거야 합니다.
Apollo에서는 다양한 종류를 ApolloLink와 ApolloCache 제공하고 있기 때문에 가장 기본적으로 사용되는 것을 사용하겠습니다.

createHttpLink는 HTTP를 통해 원격 GraphQL 서버와 연동할 수 있도록 HttpLink 객체를 생성해주는 팩토리 함수입니다.
이 함수의 인자로 연동할 GraphQL 서버의 uri를 설정해줘야 하는데, 여기서는 대륙/국가 데이터를 제공하는 공개된 GraphQL API를 사용하였습니다.
특별한 캐시 요구사항이 없다면 대부분의 경우, 가장 기본적인 InMemoryCache 옵션을 사용합니다.

GraphQL API 호출

위에서 생성한 ApolloClient 객체의 query() 메서드를 사용해서 GraphQL API 호출해보겠습니다.
query() 메서드는 queryvariables 인자로 받는데, query에는 gql 템플릿 리터럴 태그로 감싼 쿼리문을 할당합니다.
여기서 사용한 쿼리문은 변수를 포함하고 있지 않기 때문에, variables 인자는 넘길 필요가 없습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(async function () {
const { loading, error, data } = await client.query({
query: gql`
query {
continents {
code
name
}
}
`
});

console.log('loading:', loading);
console.log('error:', error);
console.log('data:', data);
})();
1
2
3
loading: false
error: undefined
data: {continents: Array[7]}

여기서 주의할 점은 query()는 Promise 객체를 리턴한다는 것입니다. 따라서, 비동기 처리를 위해 async/await 키워드를 사용해야합니다.
이 Promise 객체는 loading, error, data 프로퍼티를 갖는 객체로 resolve 됩니다.

async/await 키워드에 대한 자세한 설명은 관련 포스트을 참고 바랍니다.

이 중, data가 GraphQL 서버로 부터 응답된 데이터를 담고 있습니다.
loading은 데이터가 수신되는 동안 true였다가 false로 바뀌는데, 보통 UI를 구현할 때 데이터 로딩 중 메세지나 spinner 애니메이션을 보여주기 위해서 사용됩니다.
마지막으로 error는 예외가 발생했을 경우에, 관련 정보가 담깁니다.

[참고] async/await 키워드를 사용할 수 없는 경우

async/await 키워드를 사용할 수 없는 경우에는 리턴된 Promise 객체의 then() 메서드를 사용하면 됩니다.

Promise에 대한 자세한 설명은 관련 포스트를 참고 바랍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(function () {
client.query({
query: gql`
query {
continents {
code
name
}
}
`
})
.then(({ loading, error, data }) => {
console.log('loading:', loading);
console.log('error:', error);
console.log('data:', data);
});
})();

전체 코드

마치면서

이상으로 Apollo Client를 사용하여 GraphQL API를 호출하는 방법을 간단하게 살펴보았습니다.
Apollo Client를 이렇게 직접 사용하기 보다는 React와 같은 UI 라이브러리와 함께 사용해야 하시는 분은 아래 포스트를 참고바랍니다.

공유하기