如何在 type-graphql 中触发订阅?

Posted

技术标签:

【中文标题】如何在 type-graphql 中触发订阅?【英文标题】:How to trigger subscriptions in type-graphql? 【发布时间】:2021-01-14 03:09:38 【问题描述】:

我有一个使用 Apollo Server 和 express 建立的项目。我一直在尝试设置订阅,但它没有发生。我已按照以下链接执行所有步骤:

https://typegraphql.com/docs/subscriptions.html

此外,我最初运行订阅时无法收听。所以我用一个 http 服务器包装了我的 express 应用程序,在我的 app.listen 中,我添加了一个新的订阅服务器,然后订阅正在监听。但是现在,当我运行应该触发订阅的突变时,它不会被触发。我一直在尝试很多东西,但到目前为止,SO 或 Github 上没有任何帮助。

以下是服务器的代码


import express from "express";
import  ApolloServer  from "apollo-server-express";
import cors from "cors";
import  SubscriptionServer  from "subscriptions-transport-ws";
import  execute, subscribe  from "graphql";
import  createServer  from "http";

const main = () => 
  const app = express();

  app.use(
    cors(
      origin: "http://localhost:3000",
      credentials: true,
    )
  );
  const apolloServer = new ApolloServer(
    playground: 
      settings: 
        "request.credentials": "include",
      ,
    ,
    schema: await buildSchema(
      resolvers: [Resolver1, Resolver2, Resolver3],
      validate: false,
    ),
    context: ( req, res ) => ( req, res, redis ),
  );

  apolloServer.applyMiddleware(
    app,
    cors: false,
  );

  const server = createServer(app);

  server.listen(4000, async () => 
    console.log("Server running on port 4000");
    new SubscriptionServer(
      
        execute,
        subscribe,
        schema: await buildSchema(
          resolvers: [Resolver1, Resolver2, Resolver3],
          validate: false,
        ),
      ,
      
        server,
        path: "/graphql",
      
    );
  );
;

如果我做错了什么,请告诉我或引导我朝着正确的方向前进。

【问题讨论】:

我也遇到了同样的问题,您找到可行的解决方案了吗?如果是这样,请在这里分享。 【参考方案1】:

应该这样做:-

import 'reflect-metadata';
import express from 'express';
import  ApolloServer  from 'apollo-server-express';
import  devLogger  from './utils/constants';
import  createServer  from 'http';
import  getSchema  from './utils/schema';

const main = async () =>

    const app = express();
    const ws = createServer( app );
    const apolloServer = new ApolloServer( 
        schema: await getSchema(),

     );

    apolloServer.applyMiddleware(  app  );
    apolloServer.installSubscriptionHandlers( ws );

    const PORT = process.env.PORT || 5000;
    ws.listen( PORT, async () =>
    
        devLogger( `Server started on port $ PORT ` );
     );
;

main().catch( err => devLogger( err ) );

【讨论】:

【参考方案2】:

您不需要从 subscriptions-transport-ws 导入 SubscriptionServer。这是一个简单的 GraphQL 服务器模板。

server.ts

import "reflect-metadata";
import express from "express";
import  ApolloServer  from "apollo-server-express";
import  buildSchema  from "type-graphql";
import http from 'http';

const main = async () => 
  const app = express();
  const httpServer = http.createServer(app)

  const apolloServer = new ApolloServer(
    schema: await buildSchema(
      // Insert your resolvers here
      resolvers: [],
      validate: false
    ),
    // Not required but if you want to change your path do it here. The default path is graphql if "subscriptions" field is not passed
    subscriptions: 
      path: "/subscriptions",
      onConnect: () => console.log("Client connected for subscriptions"),
      onDisconnect: () => console.log("Client disconnected from subscriptions")
    
  );

  apolloServer.applyMiddleware( app, cors: false );
  apolloServer.installSubscriptionHandlers(httpServer)

  httpServer.listen(4000, () => console.log("Server ready at http://localhost:4000"))
;

main().catch((err) => console.error(err));

解析器

import 
  Arg,
  Mutation,
  Resolver,
  Root,

  // Required for subscription to work
  Subscription, 
  PubSub,
  PubSubEngine
 from "type-graphql";

@Resolver()
export class MessageResolver 
  @Subscription( topics: 'NOTIFICATIONS' )
  newNotification(@Root() payload: string) : string 
    return payload
  

  @Mutation(() => String)
  async sendMessage(
    @Arg('name') name: string,
    @PubSub() pubsub: PubSubEngine
  ): Promise<string> 
    pubsub.publish('NOTIFICATIONS', name)
    return name
  

注意 要回答您的问题,Typescript 很可能没有读取您编写订阅解析器的文件,从而导致没有创建 GraphQL 模式。确保将以下行添加到您的 tsconfig.json 文件中。有时,vscode 会自动导入路径并将它们添加到这一行。

  "include": [
    "./src/**/*.tsx",
    "./src/**/*.ts"
  ]

【讨论】:

以上是关于如何在 type-graphql 中触发订阅?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何在通过 EventARc 触发器创建的云发布订阅中启用排序?

如何立即触发 apollo graphql 订阅?

Pub Sub 的不同实现是不是相互配合?

如何使用 type-graphql 定义对象类型

每当我的 Apollo 订阅在 React 中被触发时,我如何调用函数?

如何仅在输入模糊时触发反应表单 valueChanges 订阅并在 Angular 2 中输入键