Created
November 28, 2019 05:45
-
-
Save swdunlop/f3eb1ef5aeeeda5a9e9866ef948ff80b to your computer and use it in GitHub Desktop.
Simple Time Server Using GQLGen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment