apollo
@nuxtjs/apollo

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

NuxtJS 内の Apollo

npm version license

警告

このバージョンには、serverPrefetch をサポートする Vue 2.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://: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://: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://: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 の設定内で関数(getAuthinMemoryCacheOptions.fragmentMatcher など)を宣言する必要がある場合、clientOptions は外部ファイルを使用して定義する必要があります

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

export default (context) => {
  return {
    httpEndpoint: 'https://: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 Option: 必須

Apollo クライアントのエンドポイントを設定します。各エンドポイントで利用可能なすべてのオプションはこちらで確認できます。

可能なユースケースが紹介されている公式 vue-apollo-cli をご確認ください。

clientConfigs.default Object: 必須

clientConfigs. Object|Path: オプション

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

認証時に設定される Cookie のトークン名。デフォルトを上書きするために、各 clientConfigstokenName オプションを提供することもできます。各リクエストが行われる際、この 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