I am using the latest version of Apollo Client in a simple React app and I am trying to pull out a header value from the response that is being used to show the size of the record set being returned.
I appreciate that this is not the most elegant way of providing the result set size, but that is how the API has currently been set up.
I was hoping to use the the middleware type options to do this, but when I inspect the response object I can't seem to pull out any headers.
The network trace does show that the response header is as expected so I suspect I am misunderstanding how to get at the underlying objects that I need.
I have checked the documentation, but nothing stands out as obvious hence the question here ...
The Apollo client does not expose the response headers to client. We can use HttpLink to send custom headers to in our requests (which we will do to authorize via 'Authorization' header), but there is no direct way to handle the response headers.
The Apollo Link library helps you customize the flow of data between Apollo Client and your GraphQL server. You can define your client's network behavior as a chain of link objects that execute in a sequence: Apollo Client.
Unlike GraphiQL, GraphQL Playground allows you to send requests with HTTP headers, such as a token needed to authenticate a user or some other kind of authorization. Make sure to first switch the tab to “HTTP HEADERS,” and then add your headers as a JSON object. By the way, you can add more than one field.
When the backend responds, the headers should include:
Access-Control-Expose-Headers: *
// or the name of your refreshToken field
Here you have the full code:
Front-end: (Apollo & React)
const httpLink = new HttpLink({ uri: URL_SERVER_GRAPHQL })
// Setup the header for the request
const middlewareAuthLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem(AUTH_TOKEN)
const authorizationHeader = token ? `Bearer ${token}` : null
operation.setContext({
headers: {
authorization: authorizationHeader
}
})
return forward(operation)
})
// After the backend responds, we take the refreshToken from headers if it exists, and save it in the cookie.
const afterwareLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
const context = operation.getContext()
const { response: { headers } } = context
if (headers) {
const refreshToken = headers.get('refreshToken')
if (refreshToken) {
localStorage.setItem(AUTH_TOKEN, refreshToken)
}
}
return response
})
})
const client = new ApolloClient({
link: from([middlewareAuthLink, afterwareLink, httpLink]),
cache: new InMemoryCache()
})
In the backend (express). If we need to refresh the token (e.g: because the actual one is going to expire)
const refreshToken = getNewToken()
res.set({
'Access-Control-Expose-Headers': 'refreshToken', // The frontEnd can read refreshToken
refreshToken
})
Documentation from: https://www.apollographql.com/docs/react/networking/network-layer/#afterware
Found the answer here: https://github.com/apollographql/apollo-client/issues/2514
Have to access it via the operation context ... interestingly the dev tools appears to show that the headers object is empty, but you can then pull named headers from it ...
const afterwareLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
const context = operation.getContext();
const { response: { headers } } = context;
if (headers) {
const yourHeader = headers.get('yourHeader');
}
return response;
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With