New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subscriptions client examples? #6
Comments
Hi @joefru, |
I did happen to read that article. I'm wondering how to include the following code in 'the nest way'...
I tried something like this:
But that yields the following build-time error:
|
Hi @joefru, components: [
{
provide: SUBSCRIPTION_SERVER,
useFactory: async () => {
const server = createServer();
return await new Promise((resolve) => server.listen(PORT, resolve));
},
}
] Then inject this component into module class: export class ApplicationModule implements NestModule {
constructor(
private readonly graphQLFactory: GraphQLFactory,
@Inject(SUBSCRIPTION_SERVER) private readonly ws,
) {}
/// rest of code
} Afterwards, create instance of configure(consumer: MiddlewaresConsumer) {
const schema = this.createSchema();
this.initSubscriptionServer(schema);
consumer
.apply(graphiqlExpress({
endpointURL: "/graphql",
subscriptionsEndpoint: `ws://localhost:${process.env.PORT || 3000}/subscriptions`
}))
.forRoutes({path: "/graphiql", method: RequestMethod.GET})
.apply(graphqlExpress(req => ({schema, rootValue: req})))
.forRoutes({path: "/graphql", method: RequestMethod.ALL});
}
initSubscriptionServer(schema) {
new SubscriptionServer({ execute, subscribe, schema}, {
server: this.ws,
path: "/subscriptions",
});
} That's all. Remember to kill server ( |
First of all, thanks for the help and quick responses. Unfortunately, I still think something is missing. I followed your directions using the nest graphql-apollo example for simplicity's sake, and I get these warnings:
When trying to access GraphiQL on localhost, the browser churns for several minutes, and eventually I get |
Will try to reproduce this locally |
Could you provide a little bit more code? What actually have you changed? Did you add a snippet that I shared with your or sth more? |
I cloned the graphql-apollo example and contained all changes within app.module.ts: import {
Inject,
Module,
MiddlewaresConsumer,
NestModule,
RequestMethod,
} from '@nestjs/common';
import { createServer } from 'http';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import { execute, subscribe } from 'graphql';
import { CatsModule } from './cats/cats.module';
@Module({
components: [
{
provide: "SUBSCRIPTION_SERVER",
useFactory: async () => {
const server = createServer();
return new Promise((resolve) => server.listen(process.env.PORT || 3000, resolve));
},
}
],
imports: [CatsModule, GraphQLModule],
})
export class ApplicationModule implements NestModule {
constructor(private readonly graphQLFactory: GraphQLFactory, @Inject("SUBSCRIPTION_SERVER") private readonly ws) {}
configure(consumer: MiddlewaresConsumer) {
const schema = this.createSchema();
this.initSubscriptionServer(schema);
consumer
.apply(graphiqlExpress({
endpointURL: '/graphql',
subscriptionsEndpoint: `ws://localhost:${process.env.PORT || 3000}/subs`
}))
.forRoutes({ path: '/graphiql', method: RequestMethod.GET })
.apply(graphqlExpress(req => ({ schema, rootValue: req })))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
createSchema() {
const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
const schema = this.graphQLFactory.createSchema({ typeDefs });
return this.graphQLFactory.createSchema({ typeDefs });
}
initSubscriptionServer(schema) {
const ss = new SubscriptionServer({execute, subscribe, schema}, {
server: this.ws,
path: "/subs",
});
}
onModuleDestroy() {
this.ws.close();
}
} |
@joefru I'm sorry.. It was my mistake 🙁 Let's use code below instead: {
provide: 'SUBSCRIPTION_SERVER',
useFactory: () => {
const server = createServer();
return new Promise(resolve => server.listen(process.env.PORT || 3000, () => resolve(server)));
},
}, |
Making progress... That change let's me successfully create the subscription server. I still can't get a subscription to listen. I have this: cats.resolvers.tsimport { Component, UseGuards } from '@nestjs/common';
import { Query, Mutation, Resolver, Subscription } from '@nestjs/graphql';
import { Cat } from './interfaces/cat.interface';
import { CatsService } from './cats.service';
import { CatsGuard } from './cats.guard';
import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
@Resolver('Cat')
export class CatsResolvers {
constructor(private readonly catsService: CatsService) {}
@Query()
@UseGuards(CatsGuard)
async getCats() {
return await this.catsService.findAll();
}
@Query('cat')
async findOneById(obj, args, context, info): Promise<Cat> {
const { id } = args;
return await this.catsService.findOneById(+id);
}
@Mutation('createCat')
async create(obj, args, context, info): Promise<Cat> {
const cat = await this.catsService.create(args.name);
pubsub.publish('catCreated', {catCreated: cat});
return cat;
}
@Subscription('catCreated')
catCreated() {
return {
subscribe: () => pubsub.asyncIterator('catCreated'),
};
}
} cats.types.graphqltype Query {
getCats: [Cat]
cat(id: ID!): Cat
catByHumanId(id: ID!): Cat
}
type Mutation {
createCat(name: String): Cat
}
type Subscription {
catCreated: Cat
}
type Cat {
id: Int
name: String
age: Int
humanId: Int
} When I run the following subscription in GraphiQL: subscription catname {
catCreated {
name
}
} It displays Ultimately, I'd love to see the graphql-apollo example be extended to include a simple working subscription like |
I updated example with the subscription server: Subscribe in one window:
Mutate in the different one:
Everythin works fine 🙂 |
Downloaded the latest example but I still get Also, what I'd really like to achieve is to have the subscription server listen on the same port as the express http server. That way, I can deploy a single application to Heroku, which only allows a single port per deployment. |
I have tested this example and it works fine for me, there's no |
I was having the same issue with [Object Object] as @joefru but I was able to resolve it by playing around with the package versions in the dependency versions. Below are the versions i ended up with to have it working. Might help you out @joefru.
|
@kamilmysliwiec i really don't understand why you delete the comment... |
Its a Community right ? and you can share your Subscription Methods to Others ? What is your point ? and problem ? |
I am out will ban nest community for sure |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Very excited about NestJS. Thinking of becoming a sponsor if it proves out for my new project.
I need to get GraphQL subscriptions working. For starters, I've implemented the example from docs, and now I'm trying to connect GraphiQL with something like this:
I'm getting
ERR_CONNECTION_REFUSED
in browser console. I feel like I'm missing the connection between GraphQL Subscriptions and WebSockets, but I can't seem to piece it together from the docs.Are there any working e2e examples out there?
The text was updated successfully, but these errors were encountered: