graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.88k stars 840 forks source link

Add Subscribe function to make easier to create Subscription Handlers #530

Closed racerxdl closed 3 years ago

racerxdl commented 4 years ago

I added Subscribe function to Object / Fields Definitions so its easier to make GraphQL Subscription Handlers. I only added the field so it wouldn't break compatibility and if you don't use it, it wont make a difference.

So for example in https://github.com/racerxdl/go-subscription-handler I did:

var rootSubscriptions = graphql.ObjectConfig{
    Name: "RootSubscriptions",
    Fields: graphql.Fields{
        "serverTime": &graphql.Field{
            Type: graphql.String,
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                err := subhandler.Subscribe(p.Context, "serverTime")

                if p.Source != nil {
                    // We received a event data
                    v, ok := p.Source.(map[string]interface{})
                    if ok && v["time"] != nil {
                        return v["time"], nil
                    }
                }

                // We didn't receive a event data, so resolve normally
                return time.Now().String(), err
            },
        },
    },
}

With that Subscribe field in the struct I could do:

var rootSubscriptions = graphql.ObjectConfig{
    Name: "RootSubscriptions",
    Fields: graphql.Fields{
        "serverTime": &graphql.Field{
            Type: graphql.String,
            Subscribe: func(p graphql.ResolveParams) error {
                return subhandler.Subscribe(p.Context, "serverTime")
            },
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                if p.Source != nil {
                    // We received a event data
                    v, ok := p.Source.(map[string]interface{})
                    if ok && v["time"] != nil {
                        return v["time"], nil
                    }
                }

                // We didn't receive a event data, so resolve normally
                return time.Now().String(), err
            },
        },
    },
}

That should help with #242

coveralls commented 4 years ago

Coverage Status

Coverage increased (+0.003%) to 92.379% when pulling c9a98c0a55260a9be71b6039b39fc29f9bbd4b06 on racerxdl:master into 02caa8943d64d9cd60bd67f2bc163676716bb963 on graphql-go:master.

racerxdl commented 4 years ago

@chris-ramon that's a quick hack to be able to do better subscriptions. There are other PRs about it (like #495 ) but this one is pretty simple and fast to review. I just add a Subscription parameter so the handler can use it and have better code.

nic commented 4 years ago

Nice job!! Any prediction of when it will be accept/merged?

jeduardocosta commented 4 years ago

I'm also interested in this change. Any news?

remorses commented 4 years ago

Instead of using a different subscribe functions we should use a channel to send events and return this channel as resolver return value

Gqlgen and graphql gophers already do this,

I don’t like the approach of this pr, it is not intuitive and difficult to integrate with pubsub libs

bhoriuchi commented 4 years ago

Instead of using a different subscribe functions we should use a channel to send events and return this channel as resolver return value

Gqlgen and graphql gophers already do this,

I don’t like the approach of this pr, it is not intuitive and difficult to integrate with pubsub libs

I gave a longer answer in my PR but the short version is that this project follows the reference implementation which has this method https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L1001 . It it also not difficult to integrate into pubsub libs if you implement the Subscribe handler https://github.com/graphql/graphql-js/blob/master/src/subscription/subscribe.js#L63

remorses commented 4 years ago

ok i think we can close this in favour of #495

racerxdl commented 3 years ago

I agree @remorses , Closing in favor of https://github.com/graphql-go/graphql/pull/495