简体   繁体   中英

GraphQL Subscriptions using Express-GraphQL

Can anyone tell me how to implement GraphQL Subscriptions using Express-GraphQL in Node?

I have also run into the same problem. I wasn't able to find a clear solution to this in the documentation. So i have just switched to graphql-yoga instead. But i did find this thread so do check it out

I've been researching this same issue.

I've read the GitHub issues for express-graphql subscriptions and a member of that repo suggested using graphql-ws on the closing comment.

Here's a link to my GitHub project shammelburg/express-graphql-api , you can npm start load grapiql to test queries and mutation.

To test subscriptions, I've created an Angular project which implements graphql-ws 's observables example. shammelburg/graphql-rxjs-angular

The Angular project also uses graphql-request for queries and mutations.

This is a very lightweight solution and works perfectly.

They've added the doc fragment mentioning Subscription Support with an example implementation in Nov 2020. But unfortunately that never got released, there's an issue here mentioning that.

My workaround for now's been switching over to Express Playground for the subscriptions-transport-ws socket (Playground doesn't support graphql-ws yet) and Apollo Sandbox for the graphql-ws .

Then my subscription creation options are the following.

Where createScopedPermissionWrapper is just an execute wrapper with @graphql-authz and createGraphqlContext a factory function validating auth and creating a custom context for my resolvers.

import { Server } from 'http'
import { useServer } from 'graphql-ws/lib/use/ws' // subscription with graphql-ws
import { SubscriptionServer } from 'subscriptions-transport-ws' // subscription with subscriptions-transport-ws

export const createSubscriptionsTransportWs = (server: Server) => {
  const wsServer = new SubscriptionServer(
    {
      schema,
      execute: createScopedPermissionWrapper(),
      subscribe,
      onConnect: (args: { authentication?: string }) =>
        createGraphqlContext({
          authentication: args.authentication,
        }),
    },
    { server, path }
  )

  const wsAddress = wsServer.server.address() as AddressInfo
  depClients.logger.success(
    `Graphql subscription socket up on ${wsAddress.address}:${wsAddress.port}${path}`
  )
}

export const createGraphqlWS = (server: Server) => {
  const wsServer = new ws.Server({ server, path })

  useServer(
    {
      schema,
      execute: createScopedPermissionWrapper(),
      subscribe,
      context: (args: { connectionParams: { authentication?: string } }) =>
        createGraphqlContext({
          authentication: args.connectionParams.authentication,
        }),
    },
    wsServer
  )

  const wsAddress = wsServer.address() as AddressInfo
  depClients.logger.success(
    `Graphql subscription socket up on ${wsAddress.address}:${wsAddress.port}${path}`
  )
}

See Authentication and Express Middleware

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');

var schema = buildSchema(`
  type Query {
    ip: String
  }
`);

const loggingMiddleware = (req, res, next) => {
  console.log('ip:', req.ip);
  next();
}

var root = {
  ip: function (args, request) {
    return request.ip;
  }
};

var app = express();
app.use(loggingMiddleware);
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM