gqlgen icon indicating copy to clipboard operation
gqlgen copied to clipboard

Can't find docs/examples of Subscriptions

Open Sequoia opened this issue 5 years ago • 12 comments

What happened?

I want to write a Subscription resolver

  • Looked through this repo
  • Looked through https://gqlgen.com

What did you expect?

  • Expected to find a section called "Subscriptions" explaining how to write them with gqlgen

More info

Through some issue searching I found a link to this: https://github.com/99designs/gqlgen/blob/master/example/chat/resolvers.go#L115-L150

That's what I'm working off of currently. It would be useful to have some part of the docs touch on subscriptions.

Sequoia avatar Dec 11 '19 15:12 Sequoia

While the chat example is a good starting point, it misses in my opinion two important parts:

  1. The channel is not closed in the cleanup. This leads to gqlgen never being able to terminate the internal go routine.
go func() {
  <-ctx.Done()
  r.mu.Lock()
  delete(room.Observers, id)
  close(events) // <-
  r.mu.Unlock()
}()
  1. The lock in this case can get blocked when there are connection issues with one client. The example buffers the channel, but I would argue that at some point the message should just be dropped so that no other clients are blocked from receiving messages.
r.mu.Lock()
for _, observer := range room.Observers {
  if observer.Username == "" || observer.Username == message.CreatedBy {
    select {
    case observer.Message <- &message:
    default:
      log.Printf("could not send message to %v\n", observer.Username)
    }
  }
}
r.mu.Unlock()

arddor avatar Dec 19 '19 08:12 arddor

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Feb 17 '20 10:02 stale[bot]

Yes, it would be nice to have some documentation on subscriptions. I have been trying to figure out how they work.

RobertoOrtis avatar Aug 08 '20 15:08 RobertoOrtis

The only other reference I can find is https://www.freecodecamp.org/news/https-medium-com-anshap1719-graphql-subscriptions-with-go-gqlgen-and-mongodb-5e008fc46451/

txbrown avatar Aug 13 '20 21:08 txbrown

The only other reference I can find is https://www.freecodecamp.org/news/https-medium-com-anshap1719-graphql-subscriptions-with-go-gqlgen-and-mongodb-5e008fc46451/

I got them working with arsmn's fork for gofiber framework. However, I am having an issue where I get an error whenever a user abruptly closes the subscription by closing the browser window/tab

https://github.com/99designs/gqlgen/issues/1281

RobertoOrtis avatar Aug 14 '20 01:08 RobertoOrtis

Bump

Naatan avatar Mar 16 '21 16:03 Naatan

Bump

justgook avatar Aug 19 '21 00:08 justgook

bump

slayerjain avatar Nov 16 '21 06:11 slayerjain

The only other reference I can find is https://www.freecodecamp.org/news/https-medium-com-anshap1719-graphql-subscriptions-with-go-gqlgen-and-mongodb-5e008fc46451/

FWIW: this is the original post on medium, which doesn't have broken formatting: https://medium.com/@anshap1719/how-to-handle-graphql-subscriptions-with-go-gqlgen-and-mongodb-1152ee6da82d

psigen avatar Jan 14 '22 06:01 psigen

Bump

Why they can't do it in over a year?

Ammce avatar Mar 13 '22 16:03 Ammce

Hey everyone,

I've just done the PR #2346 containing my suggestion for the documentation on Subscriptions. I'd be happy if you could all proof-read my document, and give me feedback if anything is unclear or if I did any typos! 🙂

Unkn0wnCat avatar Aug 28 '22 20:08 Unkn0wnCat

Thanks @Unkn0wnCat for great Subscriptions recipe! On another note i'm wondering why there is not example of GraphQL client written in Go that subsribes to a subscription? All examples I've seen are NodeJS wondering what is the reason.

AndriyKalashnykov avatar Sep 13 '22 02:09 AndriyKalashnykov

Thanks for the docs @Unkn0wnCat It has showed me direction to go however coming from node.js background. There are few concepts like event triggers based on topics like it is shown here I am now wondering how to implement this in go. Can we have similar things to those?

Also I used to see pub/sub things much in nodejs like using Redis or Google pub sub? Do we need the same things in golang?

kateile avatar Sep 24 '22 19:09 kateile

@AndriyKalashnykov I've not had to implement a subscriptions client in Go myself, but it looks like hasura/go-graphql-client has the feature you're looking for. Keep in mind I've not worked with the linked module, so I can't give you any rating or pointers on the quality of it, but it has a lot of stars as well as an active maintainer - so give it a try!

@kateile In the reference example in the recipe I've left off with the Go routine having an open channel, on top of that you could easily build your own topic-subscriptions or use a module like Google's PubSub, or a Redis client.

Something like this may work for Redis (no warranty on that, I've just typed this off the top of my head, not tried nor compiled it):

func (r *subscriptionResolver) CurrentTime(ctx context.Context) (<-chan *model.Time, error) {
	ch := make(chan *model.Time)
        rdb := GetRedisInstance() // You'll need to provide your own redis client instance 😛 

	go func() {
		for {
			pubsub := rdb.Subscribe(ctx, "timechannel")

                        incoming := pubsub.Channel()

                        for msg := range incoming {
                          myObject := UnmarshalMyObject(msg.Payload) // You'll somehow need to transform your Redis payload into the right object

                          select {
			    case ch <- myObject:

			    default:
				    fmt.Println("Channel closed.")
                                    pubsub.Close()
				    return
			    }
                        }

                        close(ch)
		}
	}()

	return ch, nil
}

Hope this helps for both of you!

Unkn0wnCat avatar Sep 25 '22 00:09 Unkn0wnCat