Apollo-server: Accessing Response in Apollo Server 2 context

Created on 30 May 2018  路  4Comments  路  Source: apollographql/apollo-server

Hi!
In Apollo Server 1 we would manually add graphqlExpress as a middleware and we could pass both the request and response to the function that returns the context, but in Apollo Server 2 we only get the request as a parameter for that function. I need to access the response in my resolvers so I can set a cookie. Any ideas?
Thanks!

鉀诧笍 feature

Most helpful comment

This doesn't work for me.

const server = new ApolloServer({
  introspection: true,
  playground: true,
  typeDefs: schema,
  resolvers,
  formatError: error => {
    // leave only the important validation error
    const message = error.message
      .replace('SequelizeValidationError: ', '')
      .replace('Validation error: ', '')

    return {
      ...error,
      message,
    }
  },
  context: async ({ req, res, connection }) => {
    if (connection) {
      return {
        models,
      }
    }
    if (req) {
      const me = await getMe(req, res)
      return {
        models,
        me,
        secret: process.env.SECRET,
      }
    }
  },
})
const getMe = async (req, res) => {
  const token = req.headers['x-token']
  if (token) {
    try {
      return jwt.verify(token, process.env.SECRET)
    } catch (e) {
      const refreshToken = req.headers['x-token-refresh']
      const newTokens = await refreshTokens(
        token,
        refreshToken,
        models,
        process.env.SECRET
      )
      if (newTokens.token && newTokens.refreshToken) {
        res.set('Access-Control-Expose-Headers', 'x-token, x-token-refresh')
        res.set('x-token', newTokens.token)
        res.set('x-token-refresh', newTokens.refreshToken)
      }
      return newTokens.user
    }
  }
}

res.set doesn't do anything.

All 4 comments

If you don't mind using 'less-documented' features for now, in Express you can get the related response via req.res

Thanks! Hopefully there are no side-effects! It would be nice if we could have the usual req, res pair passed through in the future...

This is now possible with #1161. For express the arguments to the context function is now { req, res }. For hapi, it is { request, h }

This doesn't work for me.

const server = new ApolloServer({
  introspection: true,
  playground: true,
  typeDefs: schema,
  resolvers,
  formatError: error => {
    // leave only the important validation error
    const message = error.message
      .replace('SequelizeValidationError: ', '')
      .replace('Validation error: ', '')

    return {
      ...error,
      message,
    }
  },
  context: async ({ req, res, connection }) => {
    if (connection) {
      return {
        models,
      }
    }
    if (req) {
      const me = await getMe(req, res)
      return {
        models,
        me,
        secret: process.env.SECRET,
      }
    }
  },
})
const getMe = async (req, res) => {
  const token = req.headers['x-token']
  if (token) {
    try {
      return jwt.verify(token, process.env.SECRET)
    } catch (e) {
      const refreshToken = req.headers['x-token-refresh']
      const newTokens = await refreshTokens(
        token,
        refreshToken,
        models,
        process.env.SECRET
      )
      if (newTokens.token && newTokens.refreshToken) {
        res.set('Access-Control-Expose-Headers', 'x-token, x-token-refresh')
        res.set('x-token', newTokens.token)
        res.set('x-token-refresh', newTokens.refreshToken)
      }
      return newTokens.user
    }
  }
}

res.set doesn't do anything.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manuelfink picture manuelfink  路  3Comments

hiucimon picture hiucimon  路  3Comments

stevezau picture stevezau  路  3Comments

danilobuerger picture danilobuerger  路  3Comments

bryanerayner picture bryanerayner  路  3Comments