Subscriptions-transport-ws: Use same server and port for HTTP requests and WebSockets in examples

Created on 11 Dec 2017  路  4Comments  路  Source: apollographql/subscriptions-transport-ws

I don't know why, but it seems like all the example code for subscriptions uses a different port for WebSockets. This isn't necessary because one can just listen for an upgrade request on some route on port 80 (or whatever the HTTP server is running on) and then initiate the WebSocket connection.

To make matters worse, a different port on the same hostname is considered a different origin in CORS policy. It also makes deployment more complicated.

The examples at https://www.apollographql.com/docs/react/features/subscriptions.html use a different port for WebSockets:

// Create an http link:
const httpLink = new HttpLink({
  uri: 'http://localhost:3000/graphql'
});

// Create a WebSocket link:
const wsLink = new WebSocketLink({
  uri: `ws://localhost:5000/`,
  options: {
    reconnect: true
  }
});

I would recommend getting rid of the WS_PORT in the examples in this package and just showing how to attach the transport to an existing http.Server instead.

Most helpful comment

Yup, here's how I have it in my code:

    const app = express()
    ...

    const GRAPHQL_PATH = '/graphql'
    app.use(GRAPHQL_PATH, bodyParser.json(), graphqlExpress({
      schema: graphqlSchema,
      context: {sequelize},
    }))

    const port = parseInt(requireEnv('BACKEND_PORT'))
    const httpServer = this._httpServer = app.listen(port)
    SubscriptionServer.create(
      {schema: graphqlSchema, execute, subscribe},
      {server: httpServer, path: GRAPHQL_PATH},
    )

All 4 comments

one can just listen for an upgrade request on some route on port 80 (or whatever the HTTP server is running on) and then initiate the WebSocket connection.

This is possible using this package? How?

Yup, here's how I have it in my code:

    const app = express()
    ...

    const GRAPHQL_PATH = '/graphql'
    app.use(GRAPHQL_PATH, bodyParser.json(), graphqlExpress({
      schema: graphqlSchema,
      context: {sequelize},
    }))

    const port = parseInt(requireEnv('BACKEND_PORT'))
    const httpServer = this._httpServer = app.listen(port)
    SubscriptionServer.create(
      {schema: graphqlSchema, execute, subscribe},
      {server: httpServer, path: GRAPHQL_PATH},
    )

Basically SubscriptionServer.create creates a new WebSocket.Server, I just had to look at the options for that to see that you can pass in a pre-created Node HTTP server

After hours of headaches... const Listener = restify.listen(port) did the trick!
I can fially use ws and http for GraphQL without any issues! YAY Thank you so much

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KaiWedekind picture KaiWedekind  路  4Comments

corysimmons picture corysimmons  路  5Comments

nickofthyme picture nickofthyme  路  3Comments

ozeals picture ozeals  路  3Comments

n1ru4l picture n1ru4l  路  3Comments