apolloClient.query не использует промежуточное ПО, аделает - PullRequest
0 голосов
/ 03 февраля 2019

У меня есть apolloclient с промежуточным программным обеспечением, который console.logs токен на предъявителя, потому что я не всегда аутентифицируюсь, когда я должен быть.

По некоторым причинам, кажется, что запросы от реагирует-apollo <Query />объект использует это промежуточное ПО - я вижу свое консольное сообщение - но запросы, которые я запускаю программно: apolloClient.query ничего не регистрируют (код не может это сделать, консольный журнал находится в верхней части промежуточного ПО authLink)).

Я начал свой проект с apollo-boost, прежде чем переключиться на apolloclient, поэтому я подумал, что возможно, 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 .Я никогда не использую более одного клиента-аполлона.Почему некоторые из моих запросов запускают промежуточное ПО, а другие нет?

edit:

за запрос, фактические используемые ссылки:

// 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 голосов
/ 05 февраля 2019

Оказывается, проблема связана с кешем - этот раздел в методе getApolloClient :

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

Работает, если я изменяю код для сохранения apolloClient передэто изменение применяется к копии, отправленной в ApolloProvider, например:

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. Это работает ... что-то странное, но что угодно.

...