Nuxt Nation カンファレンスが開催されます。11月12〜13日にご参加ください。

apollo
@nuxtjs/apollo

vue-apollo を使用して、Nuxt アプリに GraphQL を統合します。

NuxtJS 内での Apollo

npm version license

警告

このバージョンでは、serverPrefetch サポートを備えた Vue 2.6 以降が必要です。例:

npm install --save vue@2.6.6 vue-template-compiler@2.6.6 vue-server-renderer@2.6.6

動作させるには、package-lock.json/yarn.lock の削除/再構築が必要な場合があります。

セットアップ

1- apollo モジュールをインストールします

npm install --save @nuxtjs/apollo

または

yarn add @nuxtjs/apollo

2- @nuxtjs/apollo モジュールをロードします

// nuxt.config.js

export default {
  modules: [
    '@nuxtjs/apollo',
  ],

  apollo: {
    clientConfigs: {
      default: {
        httpEndpoint: 'https://127.0.0.1:4000',
      }
    }
  }
}

3- *.gql または *.graphql ファイルの読み込み(オプション)

graphql-tag をインストールします

npm install --save graphql-tag

または

yarn add graphql-tag

⚠️ Typescript ユーザー

ソースフォルダーに、次の内容で gql.d.ts ファイルを追加します

declare module '*.gql' {
  import { DocumentNode } from 'graphql'

  const content: DocumentNode
  export default content
}

declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const content: DocumentNode
  export default content
}

使用法

プロジェクトで vue-apollo が正常に有効になりました。

公式の例と、アプリケーション内で vue-apollo を使用する方法については、vue-apollo の公式ドキュメントを参照してください

詳細設定

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

  apollo: {
    // Sets up the apollo client endpoints
    clientConfigs: {
      // recommended: use a file to declare the client configuration (see below for example)
      default: '~/plugins/my-alternative-apollo-config.js',

      // you can setup multiple clients with arbitrary names
      alternativeClient: {
        // required
        httpEndpoint: 'https://127.0.0.1:4000',

        // override HTTP endpoint in browser only
        browserHttpEndpoint: '/graphql',

        // See https://www.apollographql.com/docs/link/links/http.html#options
        httpLinkOptions: {
          credentials: 'same-origin'
        },

        // You can use `wss` for secure connection (recommended in production)
        // Use `null` to disable subscriptions
        wsEndpoint: 'ws://127.0.0.1:4000',

        // LocalStorage token
        tokenName: 'apollo-token',

        // Enable Automatic Query persisting with Apollo Engine
        persisting: false,

        // Use websockets for everything (no HTTP)
        // You need to pass a `wsEndpoint` for this to work
        websocketsOnly: false
      },
    },
    
    /**
     * default 'apollo' definition
     */
    defaultOptions: {
      // See 'apollo' definition
      // For example: default query options
      $query: {
        loadingKey: 'loading',
        fetchPolicy: 'cache-and-network',
      },
    },
    
    // setup a global query loader observer (see below for example)
    watchLoading: '~/plugins/apollo-watch-loading-handler.js',
    
    // setup a global error handler (see below for example)
    errorHandler: '~/plugins/apollo-error-handler.js',

    // Sets the authentication type for any authorized request.
    authenticationType: 'Bearer', 

    // Token name for the cookie which will be set in case of authentication
    tokenName: 'apollo-token',

    // [deprecated] Enable the graphql-tag/loader to parse *.gql/*.graphql files
    includeNodeModules: true,

    // Cookie parameters used to store authentication token
    cookieAttributes: {
      /**
        * Define when the cookie will be removed. Value can be a Number
        * which will be interpreted as days from time of creation or a
        * Date instance. If omitted, the cookie becomes a session cookie.
        */
      expires: 7,

      /**
        * Define the path where the cookie is available. Defaults to '/'
        */
      path: '/',

      /**
        * Define the domain where the cookie is available. Defaults to
        * the domain of the page where the cookie was created.
        */
      domain: 'example.com',

      /**
        * A Boolean indicating if the cookie transmission requires a
        * secure protocol (https). Defaults to false.
        */
      secure: false,
    },
  }
}

ファイル構成を使用した Apollo の clientOptions

⚠️ apollo 設定内で関数 (例: getAuth または inMemoryCacheOptions.fragmentMatcher) を宣言する必要がある場合は、外部ファイルを使用して clientOptions を定義する必要があります

// ~/plugins/my-alternative-apollo-config.js

export default (context) => {
  return {
    httpEndpoint: 'https://127.0.0.1:4000/graphql-alt',

    /*
     * For permanent authentication provide `getAuth` function.
     * The string returned will be used in all requests as authorization header
     */
    getAuth: () => 'Bearer my-static-token',
  }
}

watchLoading の例

// ~/plugins/apollo-watch-loading-handler.js

export default (isLoading, countModifier, nuxtContext) => {
  loading += countModifier
  console.log('Global loading', loading, countModifier)
}

errorHandler の例

// ~/plugins/apollo-error-handler.js

export default ({ graphQLErrors, networkError, operation, forward }, nuxtContext) => {
  console.log('Global error handler')
  console.log(graphQLErrors, networkError, operation, forward)
}

オプション

上記の簡単な設定としてオブジェクトを追加するか、キャッシュまたはデフォルトの getAuth() 関数を上書きする必要がある場合は、クライアント構成オプションを返す構成ファイルへのパスを使用します。

clientConfigs オプション: 必須

apollo クライアントのエンドポイントを設定します。各エンドポイントで使用可能なすべてのオプションはこちらにあります

可能なユースケースが提示されている公式の vue-apollo-cli を確認してください。

clientConfigs.default Object: 必須

clientConfigs. Object|Path: オプション

tokenName String: オプション、デフォルト: 'apollo-token'

認証の場合に設定される Cookie のトークン名。各 clientConfigs でオプション tokenName を指定して、デフォルトを上書きすることもできます。各リクエストが行われると、この Cookie にある値は、以下で指定されている authenticationType によって「Authorization」HTTP ヘッダーで送信されます。

authenticationType String: オプション、デフォルト: 'Bearer'

すべての承認済みリクエストの認証タイプを設定します。GraphQL API で必要な認証タイプがデフォルトの Bearer でない場合は、これを変更してください。すべてのリクエストは、適切な HTTP ヘッダーを次の形式で送信します: "Authorization " (例: Authorization: Bearer abc123)。

バックエンドが "Authorization" という形式の Authorization ヘッダーをプレフィックスなしで要求する場合は、この値を空の文字列に設定する必要があります。

includeNodeModules Boolean: オプション、デフォルト: false

node_module フォルダー内で *.gql ファイルを使用する場合は、graphql-tag/loader を有効にしてファイルを解析できます。

認証

認証には次のメソッドを使用できます

 // set your graphql-token
 this.$apolloHelpers.onLogin(token /* if not default you can pass in client as second argument, you can set custom cookies attributes object as the third argument, and you can skip reset store as the fourth argument */)
 // unset your graphql-token
 this.$apolloHelpers.onLogout(/* if not default you can pass in client as first argument, and you can skip reset store as the second argument */)
 // get your current token (we persist token in a cookie)
 this.$apolloHelpers.getToken(/* you can provide named tokenName if not 'apollo-token' */)

完全な例を確認してください

ユーザーログイン

// ~/components/my-component.js

export default {
  methods: {
    async onSubmit () {
      const credentials = this.credentials
      try {
          const res = await this.$apollo.mutate({
              mutation: authenticateUserGql,
              variables: credentials
          }).then(({data}) => data && data.authenticateUser)
          await this.$apolloHelpers.onLogin(res.token)
      } catch (e) {
          console.error(e)
      }
    },
  }
}

ユーザーログアウト

// ~/components/my-component.js

export default {
  methods: {
    async onLogout () {
      await this.$apolloHelpers.onLogout()
    },
  }
}

getToken

// ~/middleware/isAuth.js

export default ({app, error}) => {
  const hasToken = !!app.$apolloHelpers.getToken()
  if (!hasToken) {
    error({
      errorCode:503, 
      message:'You are not allowed to see this'
    })
  }
}

apolloProvider の defaultClient にアクセスする例

Vuex アクション
// ~/store/my-store.js

export default {
  actions: {
    foo (store, payload) {
      let client = this.app.apolloProvider.defaultClient
    }
  }
}
ページコンポーネントの asyncData/fetch メソッド
// ~/components/my-component.js

export default {
  asyncData (context) {
    let client = context.app.apolloProvider.defaultClient
  }
}
nuxtServerInit
export default {
  nuxtServerInit (store, context) {
    let client = context.app.apolloProvider.defaultClient
  }
}
クライアントにアクセスするか、コンポーネント内の任意のメソッドのミューテーションとクエリを呼び出します
// ~/components/my-component.js

export default {
  methods: {
    foo () {
      // receive the associated Apollo client 
      const client = this.$apollo.getClient()

      // most likely you would call mutations like following:
      this.$apollo.mutate({mutation, variables})
      
      // but you could also call queries like this:
      this.$apollo.query({query, variables})
        .then(({ data }) => {
          // do what you want with data
        })
    }
  }
}

クライアントを取得したら、そのメソッドとプロパティにアクセスできます。API リファレンスを参照してください

任意のコンポーネントでのスマートクエリ

// nuxt.config.js

export default {
  apollo: {
    foo: {
      query: fooGql,
      variables () {
        return {
          myVar: this.myVar
        }
      }
    }
  }
}

スマートクエリの詳細については、vue-apollo ドキュメントを参照してください

node_modules での GQL ファイル認識の追加

// nuxt.config.js

export default {
  apollo: {
    clientConfigs: {
      default: '~/apollo/client-configs/default.js'
    },
    includeNodeModules: true
  }
}

アップグレード

アップグレードガイド apollo-module v3 => v4

このモジュールのバージョン 4 では、設定が不要になります。これは、vue-cli-plugin-apollo から利用可能な可能な限り最良のアプローチと、同じ設定動作を使用することを意味します。これは、独自の設定をワイヤリングする必要がなく、単に渡すだけで済むことを意味します。

次の構成を編集します

// nuxt.config.js

export default {
  apollo: {
    clientConfigs: {
      default:{
        httpEndpoint: YOUR_ENDPOINT,
        wsEndpoint: YOUR_WS_ENDPOINT
      }
    }
  }
}

アップグレードガイド apollo-client v1 => v2

このモジュールのバージョン 3 では、apollo-client 2.x を使用しています。apollo-client のアップグレードガイドに従って、すべてのミドル/アフターウェアを必ず更新してください。参照については、このソースを確認してください: https://www.apollographql.com/docs/apollo-server/migration-two-dot/

トラブルシューティング

プロキシ

CORS エラーは、ほとんどの場合、プロキシで解決されます。クライアント側のコンソールに Cross-Origin-Request エラーが表示された場合は、プロキシの設定を検討してください。クイックで簡単な設定については、https://github.com/nuxt-community/proxy-module を参照してください。

ctx.req.session - req が未定義

これは単なるプレースホルダーです。トークンを保存するために選択したストレージメカニズムに置き換える必要があります。ローカルストレージを使用した例を次に示します: https://github.com/Akryum/vue-apollo/issues/144

セットアップに貢献してワイヤーを繋げる

ルートフォルダーの .env ファイルに必要なフィールドを設定します

# cat .env
HTTP_ENDPOINT=https://your-endpoint
WS_ENDPOINT=wss://your-endpoint

index.vue では、ログインプロセスで、有効なトークンを返すミューテーションを gql エンドポイントで有効にする必要があります。

mutation authenticateUser($email:String!,$password:String!){
    authenticateUser(email: $email, password: $password) {
        token
        id
    }
}

gql バックエンドが準備できたら、次の手順で nuxt の実行を開始します

npm install
npm run dev