天天看點

graphql學習(六)

後端折騰完了,折騰前端

之前為了圖省事,我們選擇了Apollo Boost...出來混終究是要還的,為了配置攔截器,還得用Apollo Client.當然,也許是我不知道怎麼配置Apollo Boost,如果有誰知道告訴我一聲.

首先安裝必要的包:

npm install -S apollo-cache-inmemory apollo-client apollo-link apollo-link-context apollo-link-http graphql-tag apollo-link-error           

首先修改utils/apollo.js,每一段的用處,有注釋,就不一一說了. token我這裡直接寫死了 :

import {ApolloClient} from 'apollo-client'
import {HttpLink} from 'apollo-link-http'
import {InMemoryCache, IntrospectionFragmentMatcher} from 'apollo-cache-inmemory'
import {ApolloLink} from 'apollo-link'
import {onError} from 'apollo-link-error'

const httpLink = new HttpLink({
    uri: 'http://127.0.0.1:9090/graphql',    //請求路徑
    credentials: 'include'        // 請求需要帶入cookie則配置
  })

const middlewareLink = new ApolloLink((operation, forward) => {
    operation.setContext({
      headers: {
        'token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0IiwiZXhwIjoxNTgzNDk5OTE1LCJpc3MiOiJkZW1vIn0.5tXTOiLHTlRM1Uf7WHpTNyA1BaClaDz3QnfYJsHauF8',
        // 'token': sessionStorage.getItem('token') || ${token} || null 
      }
    })  //request攔截器
  
    return forward(operation).map(response => {
      return response
    })  //response攔截器
  })
  
  // 錯誤響應攔截器
  const errorLink = onError(({networkError, response}) => {
    let errorMsg = ''
    if (!!response && response.errors !== undefined && response.errors.length) {
      errorMsg = !response.errors[0].message ? '伺服器錯誤' : response.errors[0].message
    }
    if (networkError) {
      errorMsg = networkError.message
      if (networkError.result !== undefined) {
        errorMsg = networkError.result.success === false ? networkError.result.message : networkError.result.error
      }
    }
    if (errorMsg) {
      console.log('apollo client error: ' + errorMsg)
    }
  })

  const authLink = middlewareLink.concat(httpLink)
  
  const defaultOptions = {
    watchQuery: {
      fetchPolicy: 'network-only',
      errorPolicy: 'ignore'
    },
    query: {
      fetchPolicy: 'network-only',
      errorPolicy: 'all'
    }
  }
  
  // 支援聯合查詢 
  const fragmentMatcher = new IntrospectionFragmentMatcher({
    introspectionQueryResultData: {
      __schema: {
        types: [
          {
            kind: 'INTERFACE',
            name: 'Document',
            possibleTypes: [
              {name: 'MyInterface1'},
              {name: 'SomeInterface2'}
            ]
          }
        ]
      }
    }
  })

  // 需要添加請求頭
  export const apolloClient = new ApolloClient({
    link: errorLink.concat(authLink),
    cache: new InMemoryCache({fragmentMatcher}),
    connectToDevTools: true,
    defaultOptions: defaultOptions
  })
  
  // 不需要添加請求頭
  export const baseClient = new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache({fragmentMatcher}),
    connectToDevTools: true,
    defaultOptions: defaultOptions
  })           

main.js也要修改一下:

import Vue from 'vue'
import VueApollo from 'vue-apollo'
import {apolloClient,baseClient} from './utils/apollo'
import App from './App.vue'

Vue.config.productionTip = false

const apolloProvider = new VueApollo({
    clients: {
      api: apolloClient,   //需要添加請求頭
      base: baseClient
    },
    defaultClient: baseClient  //預設請求路徑,如果隻有一個請求就使用這個就行
  })
  
// Vue.use(VueApollo)
new Vue({
  apolloProvider,
  render: h => h(App),
}).$mount('#app')           

graphql/article.js做一個小修改:

import gql from 'graphql-tag'
import {apolloClient,baseClient} from '../utils/apollo'

// 文章清單
export function getArticles(params) {
 return baseClient.query({  //不需要帶上token
  query: gql `{
   articles{
    id
    title
    content
   }
  }`,
  variables: params
 })
}

// 單篇文章詳情
export function getArticle(params) {
  return apolloClient.query({ //需要帶上token
    query: gql `query ($id : Int) {
      article(id: $id) {
        id
        title
        content
      }
    }`,
    variables: params
  })
}           

其它都不用改

npm run serve           

如果檢視文章詳情,沒有帶上正确的token,浏覽器console可以看到"apollo client error: signature is invalid"

繼續閱讀