Access Response Headers in Apollo Client

I have a server that sends back a new JWT with each response. There's a simple example on the Apollo docs of setting request headers, but no mention of accessing response headers.
The main reason to do this, was accessing the Authorization
header so that I could update a JWT token that I stored on the client side.
Adding the Link
Go into your Apollo Client code. You need to make a new link:
import { ApolloLink } from '@apollo/client'
const afterwareLink = new ApolloLink((operation, forward) => {
return forward(operation).map((response) => {
const context = operation.getContext()
const authHeader = context.response.headers.get('Authorization')
localStorage.setItem('token', authHeader)
return response
})
})
The code is pretty simple! At the time of writing I couldn't find any examples of afterware in the docs. You call forward on the operation so that it is ran, and then mapping over it calls your code with the response.
Now we add the afterware link to our client:
import {
ApolloClient,
ApolloLink,
createHttpLink,
InMemoryCache,
} from '@apollo/client'
const httpLink = createHttpLink({
uri: process.env.REACT_APP_API,
})
export const client = new ApolloClient({
link: ApolloLink.from([
// place any other links before the line below
afterwareLink.concat(httpLink),
]),
cache: new InMemoryCache(),
})
This was another pain point when I set this up. I couldn't find any examples that show how to add the afterware link, while having multiple other links. You can add any other links to the start of the array, just be sure to keep the afterware concat at the end of it.
Server requirements
If you run the code above and get null
when doing
context.response.headers.get('Authorization')
it's most likely a cors issue. Your server needs to set Access-Control-Expose-Headers
for any custom headers. So this only applies if you have an Authorization header or some other custom one not listed in the cors spec.
Apollo Server
If you're using Apollo Server, here's all the config required to expose the header:
const server = new ApolloServer({
cors: {
origin: 'http://localhost:3000', // put your app origin, or * for all
exposedHeaders: ['Authorization'],
},
//other config options
})
When creating the server instance, add the cors
object and expose any headers, and set the correct app origin if you haven't already.
Conclusion
Hopefully this quick tutorial helps someone out there understand Apollo Link a bit better, and how to expose response headers to the client. Feel free to discuss with me on Twitter @zachcodes as well!