Как запускать подписки в type-graphql?

#typescript #graphql #apollo-server #graphql-subscriptions #typegraphql

#typescript #graphql #apollo-сервер #graphql-подписки #typegraphql

Вопрос:

У меня есть проект, настроенный на сервере Apollo с помощью express. Я пытался настроить подписки, но этого просто не происходит. Я выполнил все шаги согласно следующей ссылке :

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

Кроме того, я не смог прослушать, когда изначально запустил свою подписку. Итак, я подключил свое экспресс-приложение к http-серверу и в моем 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. У меня такая же проблема, вы нашли рабочее решение? Если да, пожалуйста, поделитесь этим здесь.

Ответ №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:

Вам не нужно импортировать SubscriptionServer из subscriptions-transport-ws. Вот простой шаблон сервера 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"
  ]