How to add header for apollo client in react native application
Asked Answered
J

4

9

This is how I define the apollo client with an upload link in my react native application.

I would like to add some header with a token value, which gets send with every request. But unfortunately I did not find an example for react native.

import { AsyncStorage } from 'react-native'
import { ApolloClient } from 'apollo-client'
import { createUploadLink } from 'apollo-upload-client'
import { InMemoryCache } from 'apollo-cache-inmemory'

const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql'
  }),
  cache: new InMemoryCache()
})

I would like to send this value in the header:

const token = await AsyncStorage.getItem('auth.token')

Update

I don't know how to insert the token from a AsyncStorage to the header. Await can't work here as it is not used in an async function:

const token = await AsyncStorage.getItem('auth.token') // await can't work here

// Initiate apollo client
const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      authorization: token
    }
  }),
  cache: new InMemoryCache()
})

// Wrap apollo provider
const withProvider = (Component, client) => {
  return class extends React.Component {
    render () {
      return (
        <ApolloProvider client={client}>
          <Component {...this.props} client={client} />
        </ApolloProvider>
      )
    }
  }
}

export default async () => {
  Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client))

  Navigation.startSingleScreenApp({
    screen: {
      screen: 'MainScreen'
    }
  })
}
Julesjuley answered 3/5, 2018 at 18:50 Comment(0)
I
9

createUploadLink has a headers property which matches to createHttpLink headers property.

headers: an object representing values to be sent as headers on the request

Sample

const token = await AsyncStorage.getItem('auth.token')

const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      "Some-Custom-Header": token
    }
  }),
  cache: new InMemoryCache()
})

UPDATE

const getToken = async () => {
  const token = await AsyncStorage.getItem('auth.token')
  return token
}
const token = getToken()
// Initiate apollo client
const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      authorization: token
    }
  }),
  cache: new InMemoryCache()
})
// Wrap apollo provider
const withProvider = (Component, client) => {
  return class extends React.Component {
    render () {
      return (
        <ApolloProvider client={client}>
          <Component {...this.props} client={client} />
        </ApolloProvider>
      )
    }
  }
}

export default async () => {
  Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client))

  Navigation.startSingleScreenApp({
    screen: {
      screen: 'MainScreen'
    }
  })
}
Inane answered 3/5, 2018 at 20:46 Comment(7)
It is nearly perfectly working. But how can I set the token value as I do get it from the AsyncStorage?Julesjuley
@Julesjuley just get it like you did on your code just before the client creation and then use that token variable as the value of your headerInane
Please have a look at the updated post. I'm sure it looks trivial for you, but I don't know how to get the token from the storage to the header.Julesjuley
@Julesjuley I just updated my answer. Please take a look and see if it's going to work for you.Inane
Then client is not defined for the Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client)) line which is used in the export default function.Julesjuley
@Julesjuley my mistake (it is quite late here). I updated answer again.Inane
in the example above haven't you basically hard coded the samr token for the duration of the client ? I would have thought it needs to grab the token freshly each time it makes a request?Asphaltite
D
7

I am using apollo boost, What I did was,

import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  request: async (operation) => {
    const token = await AsyncStorage.getItem('token');
    operation.setContext({
      headers: {
        authorization: token
      }
    });
  }
}
Dewy answered 30/4, 2019 at 19:7 Comment(0)
S
1

Using callback on getItem also works

import { ApolloClient, HttpLink, ApolloLink, InMemoryCache } from 'apollo-boost'

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql',
})

const authLink = new ApolloLink((operation, forward) => {
  AsyncStorage.getItem('AuthToken').then(token => {
    operation.setContext({
      headers: {
        authorization: token ? `Bearer ${token}` : '',
      },
    })
  })
  return forward(operation)
})

const apolloClient = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink),
})
Salmanazar answered 13/10, 2019 at 0:58 Comment(0)
P
-1

As for Jun 2021, I created a gist file solution that applies in both AsyncStorage and React-Redux. If you don't want to install any other dependencies e.g apollo-boost given that you are using apollo-client this is for you. I hope it works with you too.

P.S

This implementation is for setting up token or authentication headers on your apoll-client graphql request

Plethoric answered 26/6, 2021 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.