-
Notifications
You must be signed in to change notification settings - Fork 147
Apollo Subscriptions Cypher Directive #164
Comments
@albert-the-creator No, we don't support subscriptions yet. In theory, you should be able to implement the subscriptions yourself and use this library for queries and mutations, but I haven't tested that recently. Adding subscriptions is something we have on the roadmap, but haven't prioritized yet. |
First order of business for January? :/ |
@johnymontana Hi, Will, our team have learnt a lot about Neo4j and GRAND stack from you on the website. Thank you! Subscription is one of the three core (query, mutation, subscription) of GraphQL. We are longing for it so much. Hope you guys prioritize it. 🥇 Thanks a lot. :) |
@johnymontana what would be interested is |
@johnymontana I've been trying to get subscriptions to work with both apollo-server and graphql-yoga but to no avail. Is there a working example somewhere to show me where I'm off or is this just not possible to implement even with custom resolvers? Thanks! |
@erikrahm hey Erik i am building Graphql platform called @gapi aka Graphql API you can find namespace inside here https://github.com/Stradivario/gapi which has implemented working Subscriptions so let me show you some basic examples of it. First i found out about neo4j-graphql-js before 3 weeks ago and i decided to implement Schema merging with my API so i can work with both Schemas and i can extend already existing API's that i have build with this platform.Basically what i have accomplish is this @rxdi/neo4j extends functionality provided from neo4j-graphql-js i created module out of it so i can inject it like a regular module inside @rxdi ecosystem.Then i am using this module to pass my types or if i have already schema created, it will just extend your API functionality. You can find example for basic neo4j starter application here: Typescript Basic Neo4J Graphql Server
import { CoreModule, Module, Bootstrap } from "@gapi/core";
import { VoyagerModule } from "@gapi/voyager";
import { Neo4JModule } from "@rxdi/neo4j";
import { GraphQLObjectType, GraphQLString } from "graphql";
const UserType = new GraphQLObjectType({
name: "User",
fields: () => ({
id: {
type: GraphQLString
},
name: {
type: GraphQLString
}
})
});
@Module({
imports: [
CoreModule.forRoot(),
Neo4JModule.forRoot({
types: [UserType],
password: "your-password",
username: "neo4j",
address: "bolt://localhost:7687",
excludedTypes: {
query: {
exclude: ['']
},
mutation: {
exclude: ['']
}
}
}),
VoyagerModule.forRoot()
]
})
export class AppModule {}
Bootstrap(AppModule).subscribe(); SubscriptionsBasically as far as i know neo4j-graphql-js doesn't provide subscriptions inside the package since it will be used onto different servers (i suppose) let me show you my approach of dealing with subscriptions + Neo4J Graphql. Here we define our Subscriptions
Working example can be found here https://github.com/rxdi/starter-neo4j-typescript-complex import { Controller, Type, Subscription, Subscribe, PubSubService, withFilter, GraphQLInt, GraphQLNonNull, GraphQLString } from "@gapi/core";
import { Message } from "./types/message/message.type";
import { IMessage } from "./core/api-introspection";
import { graphRequest } from "@rxdi/neo4j";
import { GraphQLContext } from "./app.context";
@Controller()
export class AppQueriesController {
constructor(
private pubsub: PubSubService
) {}
@Type(Message)
@Mutation()
async CreateMessage(root, params, ctx: GraphQLContext, resolveInfo): Promise<IMessage> {
const response = await graphRequest<IMessage>(root, params, ctx, resolveInfo);
this.pubsub.publish('CREATE_MESSAGE', response);
return response;
}
@Type(Message)
@Subscribe((self: AppQueriesController) => self.pubsub.asyncIterator('CREATE_MESSAGE'))
@Subscription()
subscribeToUserMessagesBasic(message: IMessage): IMessage {
return message;
}
@Type(Message)
@Subscribe(
withFilter(
(self: AppQueriesController) => self.pubsub.asyncIterator('CREATE_MESSAGE_WITH_FILTER'),
(payload, {id}, context) => {
console.log('Subscribed User: ', id, context);
return true;
}
)
)
@Subscription({
id: {
type: new GraphQLNonNull(GraphQLInt)
}
})
subscribeToUserMessagesWithFilter(message: IMessage): IMessage {
return message;
}
}
To test the example you need to write query subscription subscribeToUserMessagesBasic {
subscribeToUserMessagesBasic {
messageId
}
} Open another browser and write CreateMessage query mutation CreateMessage {
CreateMessage(messageId:"1", channelId:"2") {
messageId
channelId
}
} You will receive the response inside your subscription. @rxdi/neo4j wrapper module can be found here https://github.com/rxdi/neo4jStarting @gapi projectJust specially for this case i decided to add also starter packs for Neo4J you can just pass argument like so.
Documentation for @gapi/cli can be found here More complex approach publishing event inside message queueWhen the application starts the whole schema is collected via Decorators applied inside Controllers.Now when we have our schema collected and bootstraping is done next step is to attach all BehaviorSubject Observables to particular resolver and from that step we got Type based string literal enums a.k.a Gapi Effects.They look like that: import { Effect, OfType, PubSubService } from "@gapi/core";
import { EffectTypes } from "../api-introspection/EffectTypes";
import { GraphQLContext } from "../../app.context";
import { IMessage } from "../api-introspection";
@Effect()
export class MessagesEffect {
constructor(
private pubsub: PubSubService
) {}
@OfType(EffectTypes.CreateMessage)
createMessageEffect(result: IMessage, args, context: GraphQLContext) {
this.pubsub.publish('CREATE_MESSAGE', result);
// this will be triggered when CreateMessage effect is executed
console.log(result, args, context);
}
} Basically with this approach you don't have to touch your @controller logic and we can publish some event after the success response for this particular Clean logic without touching scope of CreateMessage @Type(Message)
@Mutation({
messageId: {
type: GraphQLString
},
channelId: {
type: GraphQLString
}
})
CreateMessage(root, params, ctx: GraphQLContext, resolveInfo): Promise<IMessage> {
return graphRequest<IMessage>(root, params, ctx, resolveInfo);
}
import { Module } from "@gapi/core";
import { AppQueriesController } from "./app.controller";
import { MessagesEffect } from "./core/effects/messages.effect";
@Module({
controllers: [AppQueriesController],
effects: [MessagesEffect]
})
export class AppModule {} You can check for more details how to use @gapi and @rxdi Main repositories: Regards to all of you! :)) You can find me in Telegram here: |
- blocked by makeAugmentedSchema ?? - Error: Unknown type "_SubscriptionFilter" - Apparently, neo4j-graphql-js doesn't yet support Subscriptions ?? neo4j-graphql/neo4j-graphql-js#164
Uh oh!
There was an error while loading. Please reload this page.
This is more of a general question, maybe a feature request.
Looking at #153, it seems the library is compatible with subscriptions.
@johnymontana is the neo4jgraphql function supposed to be compatible with graphql subscriptions? When I tried, it failed with an error on dist/utils.js line 181 "could not access astNode of undefined." The library uses
schema.getQueryType
instead ofschema.getSubscriptionType
to get the ast node to extract the cypher directive from. It treats subscriptions as regular queries.creatzor@dd59c7b
The commit above allows me to use subscriptions in this manner (extremely raw & crude example):
The text was updated successfully, but these errors were encountered: