Vue.js
GraphQL
apollo
nuxt.js

Nuxt.jsでGraphQLを扱う方法

More than 1 year has passed since last update.

株式会社スマートドライブのオオキです。遅ればせながらSmartDrive Advent Calendar 201725日目の記事です。


はじめに

弊社ではGraphQLを採用したプロダクトを開発中です。

詳しくは弊社アドベントカレンダー4日目の記事を見てみてください。

GraphQLのススメ

開発中のプロダクトのフロントエンドではNuxt.jsを採用する予定です。

NuxtでGraphQLを扱う上で少し躓いた部分があったのでまとめてみたいと思います。


実装


apollo-module

Nuxt.jsでGraphQLを扱うためにNuxt.jsのapollo-moduleというモジュールを使います。


Nuxt.js module to use vue-apollo (integrates graphql-tag loader to parse .gql & .graphql files)


apollo-clientというGraphQLをフロントエンドで扱うライブラリをラップしているvue-apolloというライブラリをNuxt用にラップしてくれています。

まずはモジュールを追加します。

yarn add @nuxtjs/apollo

configに設定を追加し、


nuxt.config.js

{

// Add apollo module
modules: ['@nuxtjs/apollo'],

// Give apollo module options
apollo: {
clientConfigs: {
default: '~/apollo/client-configs/default.js'
}
}
}


apolloの設定を記述します。

今回はGitHubのAPIをたたいてみます。


~/apollo/client-configs/default.js

import { ApolloLink } from 'apollo-link'

import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

export default () => {
const httpLink = new HttpLink({ uri: 'https://api.github.com/graphql' })

// auth token
const token = xxxxxxxxxxxxx

// middleware
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: { Authorization: `bearer ${token}` }
})
return forward(operation)
})
const link = middlewareLink.concat(httpLink)
return {
link,
cache: new InMemoryCache()
}
}


HttpLinkにAPIのURLを格納、ApolloLinkでヘッダーにトークンを追加しています。


躓きポイント1

ここまで、READMEに記載されてる内容をコピペしてきただけなんですが、実はこれでは動きません。

なんと、apollo-clientのバージョンがv1系からv2系に上がったので、足りないライブラリがあるのです!

(その他のコードはv2系で書かれています。)

足りないものがREADMEの一番下に書いてあるので、インストールします。

yarn add apollo-link-http graphql


Query

サーバー側からデータを取得するためのクエリを書きます。

今回はGitHubのリポジトリの名前と、そのリンクを10件取得するクエリを書きます。


allRepos.gql

{

user(login:"takanorip") {
repositories(first:10) {
nodes {
name
url
}
}
}
}


コンポーネント

最後にViewの実装をします。


index.vue

<template>

<ul>
<li v-for="repo in allRepos" :key="repo.name">{{ repo.name }}</li>
</ul>
</template>

<script>
import allRepos from '~/apollo/queries/allRepos'

export default {
data: () => ({
allRepos: {}
}),
apollo: {
allRepos: {
prefetch: true,
query: allRepos,
update: ({ user }) => user.repositories.nodes
}
}
}
</script>


dataでデータの初期化をしつつ、apolloでデータを取得しています。


躓きポイント2

今回、クエリ名と取得するオブジェクトのキーが一致しない場合、updateでデータを返してあげる必要があります。

今回だと、user.repositories.nodesの中身をallReposにつっこんでいます。

下記issueに詳しく書いてあります。

https://github.com/Akryum/vue-apollo/issues/10


まとめ

弊社ではNuxt.jsやGraphQで開発したいエンジニアを絶賛募集中です!

https://www.wantedly.com/projects/156189

https://www.wantedly.com/projects/177318