Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphql subscription? #431

Open
david-vendel opened this issue Apr 13, 2023 · 3 comments
Open

Graphql subscription? #431

david-vendel opened this issue Apr 13, 2023 · 3 comments

Comments

@david-vendel
Copy link

Hello, it seems your library allows for using subscriptions-transport-ws to establish graphql subscription, which is not maintained anymore and is not recommended to be used.
Is there a way to make your library work with graphql-ws?
To be clear, I just want to use subscription next to already using query and mutation using this library. Is there an example how apollo-multi-endpoint-link can be used with graphql subscription?

Thank you for any help.

@jean9696
Copy link
Member

Hi @justdvl, it does work. Here is an example we have

import { ApolloLink, NextLink, Operation } from '@apollo/client/link/core'
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
import { getMainDefinition, hasDirectives } from '@apollo/client/utilities'
import { createClient } from 'graphql-ws'

import { createHttpLink } from './httpLink'

export class GatewayLink extends ApolloLink {
  wsLink: ApolloLink
  httpLink: ApolloLink
  constructor(env: Envs, clientName: string) {
    super()
    this.wsLink = new GraphQLWsLink(
      createClient({
        url: YOUR URL HERE,
        lazy: true,
      })
    )
    this.httpLink = createHttpLink({
      uri:  YOUR URI HERE,
      headers: {
        'X-Request-From': clientName,
      },
    })
  }

  public request(operation: Operation, forward?: NextLink) {
    if (hasDirectives(['rest'], operation.query)) {
      return forward?.(operation) ?? null
    }
    const definition = getMainDefinition(operation.query)
    if (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    ) {
      return this.wsLink.request(operation, forward)
    }
    return this.httpLink.request(operation, forward)
  }
}

@simxn1
Copy link

simxn1 commented May 2, 2023

@jean9696 It is also worth noting that it is needed to check for typeof window !== 'undefined' and only then define the wsLink, like so:

 if (typeof window !== 'undefined') {
      this.wsLink = new GraphQLWsLink(
        createClient({
          lazy: true,
          url: 'ws://localhost:8080/graphql',
        }),
      )
   }

Otherwise I get this:

Error: WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`

@david-vendel
Copy link
Author

david-vendel commented Jun 4, 2023

Thank you @jean9696. I assume I need to create 2 instances of GatewayLink, one for each BE service I connect to (as I need to maintain websocket with both services)?
How do I then use these instances with MultiAPILink? I am missing this last part.

Currently I have:

const httpLink = new MultiAPILink({
  createHttpLink: () => createHttpLink(),
  endpoints,
  httpSuffix: '',
  wsSuffix: '',
})
links.push(httpLink)

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants