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"

上一篇:k8s


下一篇:使用cdn加速oss,访问cdn域名的视频URL特别慢