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

问题描述

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

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,{
        server,path: "/graphql",}
    );
  });
};

请让我知道我做错了什么或指导我朝正确的方向前进。

解决方法

这应该做:-

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

您不需要从 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"
  ]