4

I'm trying to get websocket subscriptions working with Nuxt Apollo. For my server (8base.com) I need to send along a connectionParams object with the subscription request.

It seems Nuxt Apollo has a httpLinkOptions but what I really need is a wssLinkOptions. Anyone know of a way to do this with Nuxt? Ideally I don't have to replace Nuxt Apollo, as I'm using it all throughout the app.

Drew Baker
  • 14,154
  • 15
  • 58
  • 97
  • Hey Drew, did you end up finding a solution for this? I'm having exactly same issue but the answers don't work for me. – Katie Kim Jan 18 '23 at 05:47
  • @KatieKim yeah see accepted answer. But ultimately we stopped using Nuxt Apollo as it was just really buggy. We use GraphQL Request now and have never had any problems with it. – Drew Baker Jan 19 '23 at 12:12

3 Answers3

5

According to the docs, you can setup a subscription as a WebSocketLink.

https://www.npmjs.com/package/@nuxtjs/apollo/v/3.0.4#example-with-subscription-graphcool-as-example

  // Set up subscription
  const wsLink = new WebSocketLink({
    uri: `wss://subscriptions.graph.cool/v1/${process.env.GRAPHQL_ALIAS}`,
    options: {
      reconnect: true,
      connectionParams: () => {
        const token = process.server ? ctx.req.session : window.__NUXT__.state.session
        return {
          Authorization: token ? `Bearer ${token}` : null
        }
      }
    }
  })

And here's the full example:

Nuxt Config:

// nuxt.config.js
apollo:{
 clientConfigs:{
  default: '~/apollo/client-configs/default.js'
 }
}

Default Client Config:

// apollo/client-configs/default.js
import { ApolloLink, concat, split } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'
import 'subscriptions-transport-ws' // this is the default of apollo-link-ws

export default (ctx) => {
  const httpLink = new HttpLink({uri: 'https://api.graph.cool/simple/v1/' + process.env.GRAPHQL_ALIAS})
  const authMiddleware = new ApolloLink((operation, forward) => {
    const token = process.server ? ctx.req.session : window.__NUXT__.state.session
    operation.setContext({
      headers: {
        Authorization: token ? `Bearer ${token}` : null
      }
    })
    return forward(operation)
  })
  // Set up subscription
  const wsLink = new WebSocketLink({
    uri: `wss://subscriptions.graph.cool/v1/${process.env.GRAPHQL_ALIAS}`,
    options: {
      reconnect: true,
      connectionParams: () => {
        const token = process.server ? ctx.req.session : window.__NUXT__.state.session
        return {
          Authorization: token ? `Bearer ${token}` : null
        }
      }
    }
  })

  const link = split(
    ({query}) => {
      const {kind, operation} = getMainDefinition(query)
      return kind === 'OperationDefinition' && operation === 'subscription'
    },
    wsLink,
    httpLink
  )

  return {
    link: concat(authMiddleware, link),
    cache: new InMemoryCache()
  }
}

The Client Config subscription should work using the Vue Apollo model: https://apollo.vuejs.org/guide/apollo/subscriptions.html#setup

If you just need the basics, you may also be able to just specify your HTTP and WS endpints:

apollo:{
 clientConfigs:{
  default:{
    httpEndpoint: YOUR_ENDPOINT,
    wsEndpoint: YOUR_WS_ENDPOINT
  }
 }
}
JeremyM4n
  • 750
  • 5
  • 10
  • Thanks good find, that is the old docs, so curious if it works, but I will try it out. – Drew Baker Apr 15 '20 at 17:46
  • I'm unable to figure out how to merge this example with the current way Nuxt Apollo wants to setup Apollo: https://github.com/nuxt-community/apollo-module – Drew Baker Apr 21 '20 at 21:16
  • I added some more detail, specifically, how the Nuxt config loads the Client Config Subscription. Hope it's more helpful :) – JeremyM4n Apr 22 '20 at 00:13
3

So after trying a few different ways, this seems like the best way. Simply overwrite the wsClient using a plugin.

So in nuxt.config.js:

    plugins: [
        { src: "~/plugins/apollo-ws-client.js", mode: "client" }
    ],
    apollo: {
        clientConfigs: {
            default: "~/plugins/apollo-config-default.js"
        }
    },

In plugins/apollo-config-default.js:

export default function() {
    return {
        httpEndpoint: "https://api.8base.com/123456",
        wsEndpoint: "wss://ws.8base.com"
    }
}

Then in plugins/apollo-ws-client.js

export default ({ app }) => {
    const client = app.apolloProvider.defaultClient
    const token = app.$apolloHelpers.getToken()

    if (token) {
        client.wsClient.lazy = true
        client.wsClient.reconnect = true
        client.wsClient.connectionParams = () => {
            return {
                workspaceId: "123456",
                token: token
            }
        }
    }
}

Works great.

Drew Baker
  • 14,154
  • 15
  • 58
  • 97
-1

this is how i configure inside nuxt.config straight forward

  modules: [
    '@nuxtjs/apollo',
  ],
  apollo: {
    clientConfigs: {
      default: {
          httpEndpoint: 'your_graphql_url'
      }
    }
  },
  env: {
      WS_URL: 'ws://you_url/ws',
  }