LoginSignup
47

More than 5 years have passed since last update.

Nuxt.jsでGraphQLを扱う方法

Posted at

株式会社スマートドライブのオオキです。遅ればせながら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に詳しく書いてあります。

まとめ

弊社ではNuxt.jsやGraphQで開発したいエンジニアを絶賛募集中です!
https://www.wantedly.com/projects/156189
https://www.wantedly.com/projects/177318

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47