apollo,多個請求API
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { Message, Loading } from 'element-ui'
import { createApolloClient } from 'vue-cli-plugin-apollo/graphql-client'
import { ApolloLink, from } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { getToken } from '@/utils/auth'
import router from '../router'
import store from '../store'
Vue.use(VueApollo)
let loadingInstance = null
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP
const httpEndpointS = process.env.VUE_APP_GRAPHQL_HTTPS
const httpGuide = process.env.VUE_APP_GRAPHQL_GUIDE
// 攔截器:顯示統一載入動畫
const loadingLink = new ApolloLink((operation, forward) => {
loadingInstance = Loading.service({
lock: true,
fullscreen: true
})
return forward(operation)
})
// 攔截器:統一響應處理
const afterwareLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
if (loadingInstance) {
loadingInstance.close()
}
console.log('[Afterware] response:', response)
return response
})
})
// 攔截器:統一錯誤處理
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (loadingInstance) {
loadingInstance.close()
}
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) => {
console.log(`+++++ [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
})
}
if (networkError) {
const code = networkError.result.message
console.log(`++++++ [Network error]: ${code}`)
if (code === '400' || code === '402' || code === '403') {
Message.error('還未登入或登入已失效')
store.dispatch('silentLogout')
router.replace('/login')
} else if (code === '401') {
Message.error('您沒有足夠的許可權')
} else {
Message.error('伺服器出現未知錯誤')
}
}
})
/**
* 建立Apollo客戶端例項
*/
export function createProvider () {
const baseConfig = {
httpEndpoint,
getAuth: () => undefined
}
const linkWithLoading = from([loadingLink, afterwareLink, errorLink])
const linkWitoutLoading = from([afterwareLink, errorLink])
// 客戶端:適用於需要授權的請求,帶loading動畫
const { apolloClient: animatedApiClient } = createApolloClient({
...baseConfig,
link: linkWithLoading,
getAuth: () => getToken()
})
// 客戶端:適用於需要授權的請求,不帶loading動畫
const { apolloClient: plainClient } = createApolloClient({
...baseConfig,
link: linkWitoutLoading,
getAuth: () => getToken()
})
// 客戶端:適用於無授權限制的請求,帶loading動畫
const { apolloClient: animatedBaseClient } = createApolloClient({
...baseConfig,
link: linkWithLoading
})
// 客戶端:適用於無授權限制的請求,不帶loading動畫
const { apolloClient: plainBaseClient } = createApolloClient({
...baseConfig,
link: linkWitoutLoading
})
// 客戶端:指南,帶loading動畫
const { apolloClient: guideClient } = createApolloClient({
httpEndpoint: httpEndpointS,
link: linkWithLoading
})
// 客戶端:指南,不帶loading動畫
const { apolloClient: guideClients } = createApolloClient({
httpEndpoint: httpEndpointS,
link: linkWitoutLoading
})
// 客戶端:指南,帶loading動畫
const { apolloClient: guideIdentity } = createApolloClient({
httpEndpoint: httpGuide,
link: linkWithLoading
})
// 客戶端:指南,不帶loading動畫
const { apolloClient: guideIdentitys } = createApolloClient({
httpEndpoint: httpGuide,
link: linkWitoutLoading
})
return new VueApollo({
clients: {
'animatedApi': animatedApiClient,
'animatedBase': animatedBaseClient,
'api': plainClient,
'base': plainBaseClient,
'guide': guideClient,
'guides': guideClients,
'guideIdentity': guideIdentity,
'apiguideIdentity': guideIdentitys
},
defaultClient: animatedApiClient,
errorHandler (error) {
// eslint-disable-next-line no-console
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
}
})
}