Skip to content
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

Adding "Subscribe" field to subscription definitions #242

Closed
robbawebba opened this issue Sep 11, 2017 · 2 comments · Fixed by #495
Closed

Adding "Subscribe" field to subscription definitions #242

robbawebba opened this issue Sep 11, 2017 · 2 comments · Fixed by #495

Comments

@robbawebba
Copy link

I'm currently implementing a GraphQL subscription server and I'm interested in adding subscription logic to each subscription definition to use with my PubSub manager. Is it possible to add a custom field to a subscription definition that I can use to pass data/functions around? If not, would the core team consider this as a possible enhancement to the way subscriptions work?

The idea is to have a field similar to Resolve (possiblly called Subscribe) that will be accesible by any PubSub system that contains a function. This function would be responsible for the logic that defines how a subscription listens for events based on the client's query and publishes updates to the client. It's implementation and requirements, similar to the Resolve function, would be pretty relaxed and would rely on the developer to fill the function with the logic that they need to work with their data layer. So when a developer is definining subscriptions and needs a place to create query-specific logic for listening for events and publishing changes, they will be able to define that along side the rest of the subscription definition.

Lastly, the PubSub manager will be able to use this function when creating a new instance of a subscription.

Below is an example of what I'm trying to accomplish. This particular implementation of the proposed Subscribe field listens for changes to a RethinkDB database based on the contactID provided from the client's subscription query. After the change listener is set up, When a change to the database is received, the changes are published to the PubSub manager.

type dbChange struct {
	NewVal interface{} `gorethink:"new_val"`
	OldVal interface{} `gorethink:"old_val"`
}

var rootSubscription = graphql.NewObject(graphql.ObjectConfig{
	Name: "rootSubscription",
	Fields: graphql.Fields{
		"contactChanged": &graphql.Field{
			Type: contact,
			Args: graphql.FieldConfigArgument{
				"contactID": &graphql.ArgumentConfig{
					Type: graphql.String,
				},
			},
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				return p.Info.RootValue, nil
			},
			Subscribe: func(params graphql.ResolveParams) error {
				ID := params.Args["contactID"].(string)
				contactCursor, err := gorethink.DB("ContactsApp").
					Table("Contacts").
					Get(ID).
					Changes().
					Run(db.Session)
				if err != nil {
					fmt.Errorf(`Error reading database: %v`, err)
					return err
				}
				contactChanges := make(chan dbChange)
				contactCursor.Listen(contactChanges)
				fmt.Println("Listening for changes")

				for change := range contactChanges {
					subManager.publish("CONTACT_CHANGED", change)
				}
			},
		},
	},
})

My goal is to mimic the functionality of Apollo GraphQL's graphql-subscriptions NPM package that relies on a subscribe function associated with each subscription definition to set up the subscription:

const SOMETHING_CHANGED_TOPIC = 'something_changed';

export const resolvers = {
  Subscription: {
    somethingChanged: {
      subscribe: () => pubsub.asyncIterator(SOMETHING_CHANGED_TOPIC),
    },
  },
}

If anyone has any insight on custom fields in the subscription definition, or about this possible enhancement, I would love some feedback. Thanks for listening, and thanks for creating this library!

@gabrielruiu
Copy link

+1

@remorses
Copy link
Contributor

Currently working on an implementation that uses channels at #495

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants