Add custom header to apollo client polling request

Ron Badur picture Ron Badur · Feb 1, 2018 · Viewed 19.6k times · Source

I am using the apollo-client library to query data from my Graphql server. Some of the queries are sent to the server every 5 seconds through apollo polling ability.

Is there a generic way to add a custom header to all requests that are sent by my polling client?

Answer

Tal Z picture Tal Z · Feb 2, 2018

Two Solutions

There are two ways to do that. One is quick and easy and will work for a specific query with some limitation, and the other is a general solution that is safer and can work for multiple queries.

Quick and Easy Solution

Advantages

  • it's quick
  • and... easy

When you configure your query you can configure it using its options field, that has a context field. The value of context will be processed by the network chain. The context itself is not sent to the server, but if you add a headers field to it, it will be used in the HTTP request.

Example:

const someQuery = graphql(gql`query { ... }`, {
  options: { 
    context: { 
      headers: { 
        "x-custom-header": "pancakes"  // this header will reach the server
      } 
    },
    // ... other options  
  }
})

General Solution using a Network Link middleware

With Apollo you can add an Apollo Link that will act as a middleware and add a custom header to the request based on the context that was set by your query operation.

From the docs:

Apollo Client has a pluggable network interface layer, which can let you configure how queries are sent over HTTP

Read more about Apollo Link, the network link and Middleware concepts.

Advantages:

  • The middleware's logic can be used by any graphql operation (you set the condition)
  • Your queries don't need to "care" or know about HTTP headers
  • You can do more processing before deciding if and what headers to add to the request.
  • and more..

Setting the context

Same as the quick and easy solution, only this time we don't set the headers directly:

 {
   options: { 
     context: { 
       canHazPancakes: true //this will not reach the server
     }
   }
 }

Adding the middleware

Apollo has a specific middleware for setting the context apollo-link-context (the same can be achieved with a more general middleware).

import {setContext} from 'apollo-link-context'

//... 

const pancakesLink = setContext((operation, previousContext) => { 
  const { headers, canHazPancakes } = previousContext
  if (!canHazPancakes) { 
    return previousContext
  }

  return {
    ...previousContext,
    headers: {    
      ...headers,
      "x-with-pancakes": "yes" //your custom header
    }
  }
})

Don't forget to concat it to the network chain somewhere before your http link

const client = new ApolloClient({
  // ...
  link: ApolloLink.from([
    pancakesLink,
    <yourHttpLink>
  ])
})

There is another useful example in the docs: using a middleware for authentication.

That's it! You should get some pancakes from the server now. Hope this helps.