简体   繁体   English

GraphQL 使用 Express-GraphQL 的订阅

[英]GraphQL Subscriptions using Express-GraphQL

Can anyone tell me how to implement GraphQL Subscriptions using Express-GraphQL in Node?谁能告诉我如何在 Node 中使用Express-GraphQL实现GraphQL 订阅

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.所以我刚改用 graphql-yoga。 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.我已经阅读了 GitHub 的express-graphql订阅问题,并且该回购协议的成员建议在结束评论中使用graphql-ws

Here's a link to my GitHub project shammelburg/express-graphql-api , you can npm start load grapiql to test queries and mutation.这是我的 GitHub 项目shammelburg/express-graphql-api的链接,您可以npm start加载 grapiql 来测试查询和变异。

To test subscriptions, I've created an Angular project which implements graphql-ws 's observables example.为了测试订阅,我创建了一个 Angular 项目,它实现graphql-ws的 observables 示例。 shammelburg/graphql-rxjs-angular shammelburg/graphql-rxjs-角度

The Angular project also uses graphql-request for queries and mutations. Angular 项目也使用graphql-request进行查询和修改。

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.他们在 2020 年 11 月添加了提及订阅支持的文档片段以及示例实现。但不幸的是,它从未发布过, 这里有一个问题提到了这一点。

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 .我现在的解决方法是为subscriptions-transport-ws套接字切换到Express Playground (Playground 还不支持graphql-ws ),为graphql-wsApollo Sandbox

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.其中createScopedPermissionWrapper只是一个execute包装器,带有@graphql-authzcreateGraphqlContext工厂 function 验证身份验证并为我的解析器创建自定义上下文。

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请参见身份验证和 Express 中间件

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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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