#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"
]