apolloClient.query未使用中间件,而<query>却

时间:2019-02-03 15:34:52

标签: react-apollo apollo-client

我有一个带有中间件的apolloclient,该控制台以console.log记录了一个承载令牌,因为在适当的时候我并不总是通过身份验证。

出于某种原因,似乎来自react-apollo <Query />对象的查询使用了这种中间件-我看到了控制台消息-但是我以编程方式触发的查询apolloClient.query并未记录任何东西(代码无法执行此操作,控制台日志位于authLink中间件的顶部)。

在切换到apolloclient之前,我先使用apollo-boost启动了我的项目,因此我认为在切换之后,也许node_modules的设置不正确。但是我已经卸下并重新安装了纱线,现在那里不应该有任何阿波罗升压的痕迹。

此外,如果我将用于创建apolloclient的代码复制到我的事务中,使其使用该本地副本而不是全局副本,则中间件会启动。

即:

export const relayBBNToGraphcool = async () => {
    /* BEGIN without this code, WHICH IS ALREADY in the instantiation of apolloClient, the result is `user: null` */
    const authLink = setContext(async (req, { headers }) => {
        // get the authentication token from local storage if it exists
        let getToken = async () => await AsyncStorage.getItem(/*'access_token'*/'graphcool_token')
        const token =  await getToken()

        console.trace('token for connection to graphcool is currently', token, req.operationName)

        // return the headers to the context so httpLink can read them
        return token
            ? {
                headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : null,
                }
            }
            : { headers }
    })

    const httpLink = new HttpLink(config)
    const link = ApolloLink.from([/* retryLink, */ authLink, httpLink])

    const cache = new InMemoryCache()
    // overriding apolloClient in the global scope of this module
    const apolloClient = new ApolloClient({
        link,
        cache
    })
    /* END */    

    apolloClient.query({ query: User.self, forceFetch: true })
        .then(authneticatedUser => {
            console.trace('response', authneticatedUser)

            if(authneticatedUser.data.user === null)
                throw ('no user')

apolloClient是从 apollo-client 而不是 apollo-boost 配置的。它附加到App.js中的提供程序上:

return (
  <ApolloProvider client={this.state.apolloClient}>

使用getApolloClient()从其他文件加载-设置局部变量 apolloClient

var apolloClient //...
export const getApolloClient = () => { // ...
    apolloClient = new ApolloClient({
        link,
        cache
    }) //...
    return apolloClient

.query .mutate 的所有调用都是从该文件中的导出函数完成的,并且它们使用相同的 var apolloClient 。我从来没有实例化多个阿波罗客户。为什么我的某些查询触发了中间件,而其他查询却没有?

编辑:

每个请求,使用的实际链接:

// from src: https://github.com/kadikraman/offline-first-mobile-example/blob/master/app/src/config/getApolloClient.js
export const getApolloClient = async () => {
    const retryLink = new RetryLink({
        delay: {
            initial: 1000
        },
        attempts: {
            max: 1000,
            retryIf: (error, _operation) => {
                if (error.message === 'Network request failed') {
                    //if (_operation.operationName === 'createPost') 
                    //    return true
                }
                return false
            }
        }
    })

    // from: https://www.apollographql.com/docs/react/recipes/authentication.html
    const authLink = setContext(async (req, { headers }) => {
        // get the authentication token from local storage if it exists
        let getToken = async () => await AsyncStorage.getItem(/*'access_token'*/'graphcool_token')
        const token =  await getToken()

        console.trace('token for connection to graphcool is currently', token, req.operationName)

        // return the headers to the context so httpLink can read them
        return token
            ? {
                headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : null,
                }
            }
            : { headers }
    })

    const httpLink = new HttpLink(config)
    const link = ApolloLink.from([retryLink, authLink, httpLink])

    const cache = new InMemoryCache()

    apolloClient = new ApolloClient({
        link,
        cache
    })

    try {
        await persistCache({
        cache,
        storage: AsyncStorage
        })
    } catch (err) {
        console.error('Error restoring Apollo cache', err) // eslint-disable-line no-console
    }

    return apolloClient
}

1 个答案:

答案 0 :(得分:0)

事实证明,问题与缓存有关– getApolloClient 方法中的本节:

try {
    await persistCache({
    cache,
    storage: AsyncStorage
    })
} catch (err) {
    console.error('Error restoring Apollo cache', err) // eslint-disable-line no-console
}

如果我在将更改应用于发送到ApolloProvider的副本之前更改了保存apolloClient的代码,则可以使用该代码,

export var apolloClient

// from src: https://github.com/kadikraman/offline-first-mobile-example/blob/master/app/src/config/getApolloClient.js
export const getApolloClient = async () => {
    apolloClient = await getRawClient()
    try {
        await persistCache({
        cache,
        storage: AsyncStorage
        })
    } catch (err) {
        console.error('Error restoring Apollo cache', err) // eslint-disable-line no-console
    }

    return apolloClient
}

export const getRawClient = async () => {
    const retryLink = new RetryLink({
        delay: {
            initial: 1000
        },
        attempts: {
            max: 1000,
            retryIf: (error, _operation) => {
                if (error.message === 'Network request failed') {
                    //if (_operation.operationName === 'createPost') 
                    //    return true
                }
                return false
            }
        }
    })

    // from: https://www.apollographql.com/docs/react/recipes/authentication.html
    const authLink = setContext(async (req, { headers }) => {
        // get the authentication token from local storage if it exists
        let getToken = async () => await AsyncStorage.getItem(/*'access_token'*/'graphcool_token')
        const token =  await getToken()

        console.trace('token for connection to graphcool is currently', token, req.operationName)

        // return the headers to the context so httpLink can read them
        return token
            ? {
                headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : null,
                }
            }
            : { headers }
    })

    const httpLink = new HttpLink(config)
    const link = ApolloLink.from([/* retryLink, */ authLink, httpLink])

    const cache = new InMemoryCache()

    return new ApolloClient({
        link,
        cache
    })
}

然后,我还从该文件中重构查询和变异代码,导入apolloClient。 有效...有点奇怪,但是随便吧。