title: Apollo server set cookie to be accessed in next js app
body: <p>I have a Next.js app and I am using apollo-server-micro and apollo-client. I am unable to set a cookie session when the user hits the login mutation. Here's my server.js setup (npm start)</p>
  
  <pre><code>const express = require('express');
  const next = require('next');
  const { apolloServer } = require('pages/api/graphql');
  const cookieSession = require('cookie-session');
  
  const dev = process.env.NODE_ENV !== 'production';
  const app = nextApp({ dev });
  const handle = app.getRequestHandler();
  
  app.prepare().then(() =&gt; {
    const server = express();
  
    server.use(express.static('./public'));
  
    server.use(
          '/api',
          cookieSession({
              httpOnly: false,
              keys: ['super-secret-key'],
              maxAge: 24 * 60 * 60 * 1000,
              name: 'xyz',
          })
      );
  
    server.get('*', handle);
  
    server.listen(8000, () =&gt; {
      console.log('Server running on port 8000');
    })
  })
  </code></pre>
  
  <p>Within <code>pages/api/graphql.js</code>, I have the following piece of code (straight from Next.js documentation)</p>
  
  <pre><code>import { ApolloServer } from 'apollo-server-micro'
  import { schema } from '../../apollo/schema'
  
  export const apolloServer = new ApolloServer({
    schema,
    context: (ctx) =&gt; {
      return ctx.req;
    }
  })
  
  export const config = {
    api: {
      bodyParser: false
    }
  }
  
  export default apolloServer.createHandler({ path: '/api/graphql' })
  </code></pre>
  
  <p>Here's the mutation for logging in</p>
  
  <pre><code>const jobs = require('../data/jobs');
  const users = require('../data/users');
  
  const getUserByEmail = email =&gt; users.find(user =&gt; user.email === email);
  
  export const resolvers = {
    Query: {
      viewer (_parent, _args, _context, _info) {
        return { id: 1, name: 'John Smith', status: 'cached' }
      },
      jobs: (parent, args, context, info) =&gt; {
        return jobs;
      }
    },
  
    Mutation: {
      login: (parent, args, context, info) =&gt; {
        const { email } = args;
        const user = getUserByEmail(email);
        console.log(context.headers);
        if (user) {
          context.req = {
            ...context.req,
            session: user
          }
          return user;
        }
      }
    }
  }
  </code></pre>
  
  <p>There's no encryption and all for now, I just want to get this up and running for now. How would I set the session (so that the cookie appears in Chrome and is available for future incoming requests)</p>
  
  <p>Update: Apollo Client Configuration</p>
  
  <pre><code>import React from 'react'
  import Head from 'next/head'
  import { ApolloProvider } from '@apollo/react-hooks'
  import { ApolloClient } from 'apollo-client'
  import { InMemoryCache } from 'apollo-cache-inmemory'
  
  let apolloClient = null
  
  /**
   * Creates and provides the apolloContext
   * to a next.js PageTree. Use it by wrapping
   * your PageComponent via HOC pattern.
   * @param {Function|Class} PageComponent
   * @param {Object} [config]
   * @param {Boolean} [config.ssr=true]
   */
  export function withApollo (PageComponent, { ssr = true } = {}) {
    const WithApollo = ({ apolloClient, apolloState, ...pageProps }) =&gt; {
      const client = apolloClient || initApolloClient(apolloState)
      return (
        &lt;ApolloProvider client={client}&gt;
          &lt;PageComponent {...pageProps} /&gt;
        &lt;/ApolloProvider&gt;
      )
    }
  
    // Set the correct displayName in development
    if (process.env.NODE_ENV !== 'production') {
      const displayName =
        PageComponent.displayName || PageComponent.name || 'Component'
  
      if (displayName === 'App') {
        console.warn('This withApollo HOC only works with PageComponents.')
      }
  
      WithApollo.displayName = `withApollo(${displayName})`
    }
  
    if (ssr || PageComponent.getInitialProps) {
      WithApollo.getInitialProps = async ctx =&gt; {
        const { AppTree } = ctx
  
        // Initialize ApolloClient, add it to the ctx object so
        // we can use it in `PageComponent.getInitialProp`.
        const apolloClient = (ctx.apolloClient = initApolloClient())
  
        // Run wrapped getInitialProps methods
        let pageProps = {}
        if (PageComponent.getInitialProps) {
          pageProps = await PageComponent.getInitialProps(ctx)
        }
  
        // Only on the server:
        if (typeof window === 'undefined') {
          // When redirecting, the response is finished.
          // No point in continuing to render
          if (ctx.res &amp;&amp; ctx.res.finished) {
            return pageProps
          }
  
          // Only if ssr is enabled
          if (ssr) {
            try {
              // Run all GraphQL queries
              const { getDataFromTree } = await import('@apollo/react-ssr')
              await getDataFromTree(
                &lt;AppTree
                  pageProps={{
                    ...pageProps,
                    apolloClient
                  }}
                /&gt;
              )
            } catch (error) {
              // Prevent Apollo Client GraphQL errors from crashing SSR.
              // Handle them in components via the data.error prop:
              // https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
              console.error('Error while running `getDataFromTree`', error)
            }
  
            // getDataFromTree does not call componentWillUnmount
            // head side effect therefore need to be cleared manually
            Head.rewind()
          }
        }
  
        // Extract query data from the Apollo store
        const apolloState = apolloClient.cache.extract()
  
        return {
          ...pageProps,
          apolloState
        }
      }
    }
  
    return WithApollo
  }
  
  /**
   * Always creates a new apollo client on the server
   * Creates or reuses apollo client in the browser.
   * @param  {Object} initialState
   */
  function initApolloClient (initialState) {
    // Make sure to create a new client for every server-side request so that data
    // isn't shared between connections (which would be bad)
    if (typeof window === 'undefined') {
      return createApolloClient(initialState)
    }
  
    // Reuse client on the client-side
    if (!apolloClient) {
      apolloClient = createApolloClient(initialState)
    }
  
    return apolloClient
  }
  
  /**
   * Creates and configures the ApolloClient
   * @param  {Object} [initialState={}]
   */
  function createApolloClient (initialState = {}) {
    const ssrMode = typeof window === 'undefined'
    const cache = new InMemoryCache().restore(initialState)
  
    // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
    return new ApolloClient({
      ssrMode,
      link: createIsomorphLink(),
      cache
    })
  }
  
  function createIsomorphLink () {
    if (typeof window === 'undefined') {
      const { SchemaLink } = require('apollo-link-schema')
      const { schema } = require('./schema')
      return new SchemaLink({ schema })
    } else {
      const { HttpLink } = require('apollo-link-http')
      return new HttpLink({
        uri: '/apii/graphql',
        credentials: 'same-origin'
      })
    }
  }
  </code></pre>
  
  <p>Updated: Apollo-server config using apollo micro</p>
  
  <pre><code>import { ApolloServer } from 'apollo-server-micro'
  import { schema } from '../../apollo/schema'
  
  export const apolloServer = new ApolloServer({
    schema,
    context: (ctx) =&gt; {
      return ctx.req;
    }
  })
  
  export const config = {
    api: {
      bodyParser: false
    }
  }
  
  export default apolloServer.createHandler({ path: '/api/graphql' })
  </code></pre>