Nathanael
Nathanael

Reputation: 1002

Dynamic headers for Apollo GraphQL (outside of middleware

Since the Apollo link middleware appears to be defined upon construction, I'm wondering how I would go about passing in dynamic headers.

Specifically I have an authentication system where signIn and signUp don't require a header for the token. But any authenticated API calls rely singularly on the token for user context. So in cases where a token exists (localStorage.getItem('token');) it uses that token to authenticate. Otherwise it uses the token passed back from signUp/signIn to authenticate.

So I want to know how to pass in a header dynamically to a query/mutation component.

<Query query={query}>
    {({ loading, error, data }) => {
        if (loading) return "Loading...";
        if (error) return `Error! ${error.message}`;
        return (
            <select className={"CompanySelector"}>
                {data.companies.map(companies => (
                    <option className={"CompanySelection"} key={companies.id} value={companies.name}>
                        {companies.name}
                    </option>
                ))}
            </select>
        );
    }}
</Query>

I tried wrapping the query, but Apollo doesn't seem to take a graphql function as an argument.

export const wrap = (query, token) => {
    return graphql(query, {
        options: {
            context: {
                headers: {
                    'x-token': token
                }
            }
        }
    })
};

Here is the query:

export const COMPANIES = gql`
    query companies{
        companies{
            name, id
        }
    }
`;

Upvotes: 2

Views: 3063

Answers (1)

Rick Sullivan
Rick Sullivan

Reputation: 188

Query supports a context prop, so you can use it to configure query-specific authorization:

<Query
  context={{
    headers: {
      'x-token': localStorage.getItem('token')
    }
  }}
>
  {({ loading, data }) => // render the stuff
</Query>

And handle custom headers through the opt in your Apollo client's fetch function:

const httpLink = new HttpLink({
    # ...,
    fetch: (uri, opts) =>
      window.fetch(uri, {
        ...opts,
        headers: {
          'x-token': opts.headers && opts.headers['x-token'] || getTokenDefaultWay()
        }
      })
  })
)

Upvotes: 2

Related Questions