简体   繁体   中英

How to extend the context object of a GraphQL call?

I'm having the following GraphQL server call in a standard module:

export default () => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

That is used together with passport:

app.use(
    "/graphql",
    passport.authenticate("jwt", { session: false }),
    appGraphQL()
);

Everything is working file. Passport extends my req to get a logged user object that is used on my GraphQL calls to queries or mutations:

...
    resolve(source, args, context) {
        console.log("CURRENT USER OBJECT")
        console.log(context.user)
...

All fine.

Now I need to extend my context to add some custom resolvers, so my first try is:

export default () => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        context: resolvers,
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

As GraphQL docs says, this overrides the original req context and my context.user on queries and mutations stops working.

How can I properly extend the current context to add some more fields, instead of overriding it? Another unsuccessfull try:

export default (req) => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        context: {
            user: req.user,
            resolvers: resolvers
        },
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

This approach is not working... I'm getting the following error:

  user: req.user,
                ^

TypeError: Cannot read property 'user' of undefined

[edit] My latest try is from my example on Apollo Docs :

export default () => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        context: ({ req }) => ({
            user: req.user
        }),
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

Now my context is a function in my resolver:

console.log(context)
console.log(context.user)

Returns:

[Function: context]
undefined

Getting crazy with this simple thing...

Assuming you're using express-graphql , graphqlHTTP is a function that takes some configuration parameters and returns an express middleware function. Normally, it's used like this:

app.use(
  '/graphql',
  graphqlHTTP({ ... })
)

However, instead of an object, graphqlHTTP can also take a function that returns an object as shown in the docs .

app.use(
  '/graphql',
  graphqlHTTP((req, res, graphQLParams) => {
    return { ... }
  })
)

In this way, you can utilize the req , res or graphQLParams parameters inside your configuration object.

app.use(
  '/graphql',
  graphqlHTTP((req, res, graphQLParams) => {
    return {
      schema,
      // other options
      context: {
        user: req.user,
        // whatever else you want
      }
    }
  })
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM