I was recently tasked with modifying an Apollo-based GraphQL endpoint served by a Meteor application to set a field in the resolvers’ context based on a HTTP header pulled out of the incoming GraphQL request.
This should be an easy, well-documented ask.
Unfortunately, Meteor’s Apollo integration seems to exist in an awkward, undocumented state. The createApolloServer function exposed by the meteor/apollo package doesn’t seem to have any real documentation anywhere I could find, and the Github repository linked to by the package doesn’t seem to relate to the code in question.
How can I access the current HTTP request when building my resolvers’ context?
With no documentation to guide me, I dove into the package’s source code on my machine to find answers. The source for the package in question lives in ~/.meteor/packages/apollo/<version>/os/src/main-server.js on my machine. The createApolloServer function accepts a customOptions object as its first argument. I quickly learned after digging through the source that if customOptions is a function, createApolloServer will call that function with the current request (req) as its only argument, and use the function call’s result as the value of customOptions:
const customOptionsObject =
typeof customOptions === 'function'
? customOptions(req)
: customOptions;
This means we need to change our current call to createApolloServer from something like this:
import { createApolloServer } from "meteor/apollo";
createApolloServer({ schema }, { path });
To something like this:
createApolloServer(
req => ({
context: {
someValue: req.headers['some-value']
},
schema
}),
{ path }
);
This information is probably only pertinent to myself and an ever-shrinking number of people, but if you’re one of those people, I hope this helps.