package main import ( "context" "net/http" "strings" "time" "github.com/99designs/gqlgen/handler" ) //go:generate go run github.com/99designs/gqlgen func main() { playgroundHandler := handler.Playground("What Time is It?", `/graphql`) exec := NewExecutableSchema(Config{Resolvers: root{}}) graphqlHandler := handler.GraphQL(exec) http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) { switch { case r.Method != `GET`: graphqlHandler.ServeHTTP(w, r) case canUpgrade(r, `websocket`): graphqlHandler.ServeHTTP(w, r) default: playgroundHandler.ServeHTTP(w, r) } }) err := http.ListenAndServe(`localhost:8080`, nil) if err != nil { panic(err) } } func canUpgrade(r *http.Request, protocol string) bool { for _, v := range r.Header[`Upgrade`] { if strings.SplitN(v, " ", 2)[0] == protocol { return true } } return false } type root struct{} func (_ root) Query() QueryResolver { return query{} } func (_ root) Subscription() SubscriptionResolver { return subscription{} } type query struct{} func (_ query) Time(_ context.Context) (string, error) { return time.Now().Format(timeFormat), nil } type subscription struct{} func (r subscription) TimeChanged(ctx context.Context) (<-chan string, error) { ret := make(chan string) go r.trackTimeChanges(ctx, ret) return ret, nil } func (r subscription) trackTimeChanges(ctx context.Context, ret chan<- string) { t := time.NewTicker(time.Second) defer t.Stop() start := time.Now().Format(timeFormat) println(`.. starting to track time changes at`, start) defer println(`.. done tracking time changes since`, start) done := ctx.Done() select { case <-done: return case ret <- start: } for { select { case <-done: return case t := <-t.C: now := t.Format(timeFormat) select { case <-done: return case ret <- now: } } } } const timeFormat = `2006-01-02 15:04:05`