Vue.jsで使うGraphQLクライアントライブラリ

Vue.jsでGraphQL使ってみようかと思った時、GraphQLクライアントが結構ゴチャついててどのライブラリを組み合わせて使えばいいのか分かりにくかったのでまとめました

結論

コンポーネント内でリクエストの送信をするなら vue-apollo
Vuexのアクションでリクエストを送信するなら apollo-client
AWS Amplify + AppSyncの組み合わせなら aws-amplify

vue-apollo

コンポーネントに組み込むタイプのやつです。コンポーネントapolloオプション生やしてそこで指定されたリクエストはmountedで呼ばれます。

apolloオプション、ちょっと邪悪感が否めませんが、小さなアプリケーションを使うときはこいつで十分です。コンポーネントのテストにはvue-test-utilsなんかを使えば良いのではないでしょうか。

Vuexのライフサイクルとは合わないのでVuexのアクションでGraphQLエンドポイントにリクエスト投げる使い方をしたい人には向きません。

サンプルソース

<template>
  <div><span>{{ getTodo }}</span></div>
</template>

<script>
import Query from '@/apollo/query.gql'

export default {
  data() {
    return {
      getTodo: {}
    }
  },
  apollo: {
    getTodo: {
      variables: {
        id: 1
      },
      prefetch: true,
      query: Query,
    }
  },
  methods: {
  },
  async mounted () {
    this.$apollo.queries.getTodo.refetch().then(data => console.log(data))
  }
}
</script>

apollo-module

Nuxtでvue-apolloを使うためにvue-apolloをラップしたライブラリです。役割はvue-apolloと同じなので省略。

apollo-client

vue-apolloaws-appsync-sdkの大元になるライブラリです。ドキュメントの最初の方に書いてある通り、ビューレイヤーに組み込むことでキャッシュなどの機能を十分発揮してくれます。

こんな感じで簡単に書くことができます。

import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';

const client = new ApolloClient({
  uri: 'https://graphql.example.com'
});

client.query({
  query: gql`
    query TodoApp {
      todos {
        id
        text
        completed
      }
    }
  `,
})
  .then(data => console.log(data))
  .catch(error => console.error(error));

apollo-link

ただ単純にGraphQLのリクエストのみを送りたいときはこいつです。query/mutationを送りたいときはapollo-link-httpを使います。

こいつはexecutemakePromiseを組み合わせてよく便利に使っています。

import { execute, makePromise } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import gql from 'graphql-tag'
import query from './query.gql'

const operation = {
  query: gql`${query}`
}
const uri = 'http://localhost:4000/graphql/'
const headers = {}
const link = new HttpLink({ uri, headers })

makePromise(execute(link, operation))
  .then(data => {
    if (this.debug) console.log(`received data ${JSON.stringify(data, null, 2)}`)
    return data
  })
  .catch(error => {
    if (this.debug) console.log(`received error :${error}\n${this.baseURL}: ${query}`)
    return { error: error }
  })

aws-amplify

AmplifyでAppSync立てたならこいつを使うのが一番使い勝手良さそうです。というかCognitoのトークン取ってくる機能もAppSyncにリクエスト投げるのもこいつだけで完結できます。

ライブラリとしてすごく便利でいろんなことをやってくれるのですが「お前なんで勝手にそんなことしてるんだよ・・・」みたいな何でも詰め込んだ感じではなく適度に薄く使いやすいやつです。

※vue-apolloのようにコンポーネントに組み込んでよしなに勝手にやってくれるようなことはしません

ドキュメントからのコピペですがこんな感じのコードです。

import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as queries from './graphql/queries';

// Simple query
const allTodos = await API.graphql(graphqlOperation(queries.listTodos));
console.log(allTodos);

// Query using a parameter
const oneTodo = await API.graphql(graphqlOperation(queries.getTodo, { id: 'some id' }));
console.log(oneTodo);

aws-appsync-sdk

apollo-clientをラップしたライブラリで、query/mutationはapollo-clientとほとんど変わらなくてsubscriptionやofflineを使うには少し便利そうです。

コンポーネントに組み込まずに使う方法ありそうですが使ってないので不明です。サンプルではコンポーネントに組み込んでthis.$apolloで参照する使い方しか書かれていません。

感想

apolloさん関係のライブラリを使おうとする度に「俺はただいい感じにGraphQLのエンドポイントへfetch投げてくれるだけで満足するんだ・・・ただそれだけでいいんだ・・・」って気持ちになります。