【问题标题】:How to trigger subscriptions in type-graphql?如何在 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",
      }
    );
  });
};

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

【问题讨论】:

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

标签: typescript graphql apollo-server graphql-subscriptions typegraphql


【解决方案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"
      ]
    

    【讨论】:

      猜你喜欢
      • 2020-01-05
      • 1970-01-01
      • 2019-01-24
      • 2017-08-31
      • 2019-08-16
      • 2017-07-27
      • 2020-09-20
      • 2019-11-25
      • 2018-02-25
      相关资源
      最近更新 更多