Skip to content

Commit

Permalink
initial set-up graphql listener
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeroen Rinzema committed Mar 10, 2020
1 parent 6bfd7fd commit 46418fd
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ endpoint "checkout" "http" "json" {
endpoint = "/checkout"
}
endpoint "checkout" "graphql" "json" {
name = "data"
}
flow "checkout" {
input "schema.Object" {
}
Expand Down
3 changes: 3 additions & 0 deletions examples/todo/flow.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ endpoint "todo" "http" "json" {
method = "GET"
}

endpoint "todo" "graphql" "json" {
}

flow "todo" {
input "proto.Query" {}

Expand Down
9 changes: 9 additions & 0 deletions examples/todo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/jexia/maestro"
"github.com/jexia/maestro/codec/json"
"github.com/jexia/maestro/codec/proto"
"github.com/jexia/maestro/protocol/graphql"
"github.com/jexia/maestro/protocol/http"
"github.com/jexia/maestro/schema/protoc"
"github.com/jexia/maestro/specs"
Expand All @@ -23,19 +24,27 @@ func main() {
panic(err)
}

graph, err := graphql.NewListener(":9090", specs.Options{})
if err != nil {
panic(err)
}

_, err = maestro.New(
maestro.WithPath(".", false),
maestro.WithSchema(collection),
maestro.WithCodec(json.NewConstructor()),
maestro.WithCodec(proto.NewConstructor()),
maestro.WithCaller(http.NewCaller()),
maestro.WithListener(listener),
maestro.WithListener(graph),
)

if err != nil {
panic(err)
}

go graph.Serve()

err = listener.Serve()
if err != nil {
panic(err)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/francoispqt/gojay v1.2.13
github.com/golang/protobuf v1.3.2
github.com/google/go-cmp v0.4.0 // indirect
github.com/graphql-go/graphql v0.7.9
github.com/hashicorp/hcl/v2 v2.3.0
github.com/jhump/protoreflect v1.6.0
github.com/julienschmidt/httprouter v1.3.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/graphql-go/graphql v0.7.9 h1:5Va/Rt4l5g3YjwDnid3vFfn43faaQBq7rMcIZ0VnV34=
github.com/graphql-go/graphql v0.7.9/go.mod h1:k6yrAYQaSP59DC5UVxbgxESlmVyojThKdORUqGDGmrI=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down
69 changes: 69 additions & 0 deletions protocol/graphql/graphql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package graphql

import (
"encoding/json"
"log"
"net/http"
"sync"

"github.com/graphql-go/graphql"
"github.com/jexia/maestro/protocol"
"github.com/jexia/maestro/specs"
)

// NewListener constructs a new listener for the given addr
func NewListener(addr string, opts specs.Options) (protocol.Listener, error) {
return &Listener{
server: &http.Server{
Addr: addr,
},
}, nil
}

// Listener represents a GraphQL listener
type Listener struct {
schema graphql.Schema
mutex sync.RWMutex
server *http.Server
}

// Name returns the name of the given listener
func (listener *Listener) Name() string {
return "graphql"
}

// Serve opens the GraphQL listener and calls the given handler function on reach request
func (listener *Listener) Serve() error {
listener.server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
listener.mutex.RLock()
defer listener.mutex.RUnlock()

query := r.URL.Query().Get("query")
result := graphql.Do(graphql.Params{
Schema: listener.schema,
RequestString: query,
})

json.NewEncoder(w).Encode(result)
})

err := listener.server.ListenAndServe()
if err == http.ErrServerClosed {
return nil
}

return err
}

// Handle parses the given endpoints and constructs route handlers
func (listener *Listener) Handle(endpoints []*protocol.Endpoint) error {

log.Println(endpoints)

return nil
}

// Close closes the given listener
func (listener *Listener) Close() error {
return nil
}
2 changes: 1 addition & 1 deletion protocol/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (call *Call) Close() error {
func NewListener(addr string, opts specs.Options) (protocol.Listener, error) {
log.WithField("add", addr).Info("Constructing new HTTP listener")

options, err := ParseEndpointOptions(opts)
options, err := ParseListenerOptions(opts)
if err != nil {
return nil, err
}
Expand Down
36 changes: 36 additions & 0 deletions protocol/http/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,42 @@ import (
"github.com/jexia/maestro/specs"
)

// ListenerOptions represents the available HTTP options
type ListenerOptions struct {
ReadTimeout time.Duration
WriteTimeout time.Duration
}

// ParseListenerOptions parses the given specs options into HTTP options
func ParseListenerOptions(options specs.Options) (*ListenerOptions, error) {
result := &ListenerOptions{
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
}

read, has := options["read_timeout"]
if has {
duration, err := time.ParseDuration(read)
if err != nil {
return nil, err
}

result.ReadTimeout = duration
}

write, has := options["write_timeout"]
if has {
duration, err := time.ParseDuration(write)
if err != nil {
return nil, err
}

result.WriteTimeout = duration
}

return result, nil
}

// EndpointOptions represents the available HTTP options
type EndpointOptions struct {
Method string
Expand Down

0 comments on commit 46418fd

Please sign in to comment.