From b7e607f801647f89addff13b0ebf2f9dc83ddca2 Mon Sep 17 00:00:00 2001 From: Mantas Vidutis Date: Fri, 10 May 2019 14:44:12 -0700 Subject: [PATCH 1/2] pass variables along with outgoing request to backend graphql server --- pkg/middleware/invoker.go | 6 ++++++ pkg/proxy/http/proxy.go | 29 ++++++++++++----------------- pkg/proxy/proxy.go | 1 + 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/pkg/middleware/invoker.go b/pkg/middleware/invoker.go index e571db2f3..da64ac711 100644 --- a/pkg/middleware/invoker.go +++ b/pkg/middleware/invoker.go @@ -8,6 +8,12 @@ import ( "io" ) +type GraphQLRequest struct { + OperationName string `json:"operationName,omitempty"` + Query string `json:"query"` + Variables map[string]interface{} `json:"variables,omitempty"` +} + type Invoker struct { middleWares []GraphqlMiddleware parse *parser.Parser diff --git a/pkg/proxy/http/proxy.go b/pkg/proxy/http/proxy.go index 9d542b55d..28156c208 100644 --- a/pkg/proxy/http/proxy.go +++ b/pkg/proxy/http/proxy.go @@ -25,11 +25,6 @@ type ProxyRequest struct { Proxy *Proxy } -type GraphqlJsonRequest struct { - OperationName string `json:"operationName,omitempty"` - Query string `json:"query"` -} - func (pr *ProxyRequest) AcceptRequest(buff *bytes.Buffer) error { idx, invoker := pr.Proxy.InvokerPool.Get() @@ -40,15 +35,7 @@ func (pr *ProxyRequest) AcceptRequest(buff *bytes.Buffer) error { return err } - var graphqlJsonRequest GraphqlJsonRequest - err = json.NewDecoder(pr.Body).Decode(&graphqlJsonRequest) - if err != nil { - return err - } - - query := []byte(graphqlJsonRequest.Query) - - err = invoker.InvokeMiddleWares(pr.Context, query) // TODO: fix nil + err = invoker.InvokeMiddleWares(pr.Context, []byte(pr.GraphQLRequest.Query)) // TODO: fix nil if err != nil { return err } @@ -62,9 +49,10 @@ func (pr *ProxyRequest) AcceptRequest(buff *bytes.Buffer) error { } func (pr *ProxyRequest) DispatchRequest(buff *bytes.Buffer) (io.ReadCloser, error) { - - req := GraphqlJsonRequest{ + req := middleware.GraphQLRequest{ Query: buff.String(), + OperationName: pr.GraphQLRequest.OperationName, + Variables: pr.GraphQLRequest.Variables, } out := bytes.Buffer{} @@ -117,7 +105,14 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { pr.Body = r.Body pr.Context = p.SetContextValues(r.Context(), r.Header, config.AddHeadersToContext) - err := pr.AcceptRequest(buff) + err := json.NewDecoder(pr.Body).Decode(&pr.GraphQLRequest) + if err != nil { + p.BufferPool.Put(buff) + p.HandleError(err, w) + return + } + + err = pr.AcceptRequest(buff) if err != nil { p.BufferPool.Put(buff) p.HandleError(err, w) diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index b6eac46f8..a234fcad6 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -21,6 +21,7 @@ type Request struct { RequestURL url.URL Body io.Reader Context context.Context + GraphQLRequest middleware.GraphQLRequest } type RequestInterface interface { From 37d16db633a97a78898e0b6289d624d85f83452f Mon Sep 17 00:00:00 2001 From: Mantas Vidutis Date: Fri, 10 May 2019 15:04:56 -0700 Subject: [PATCH 2/2] test for variable proxy --- pkg/proxy/http/proxy_test.go | 46 ++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/pkg/proxy/http/proxy_test.go b/pkg/proxy/http/proxy_test.go index ceeac6b65..8ef77df68 100644 --- a/pkg/proxy/http/proxy_test.go +++ b/pkg/proxy/http/proxy_test.go @@ -21,8 +21,8 @@ func TestProxyHandler(t *testing.T) { if err != nil { t.Fatal(err) } - if string(body) != assetOutput { - t.Fatalf("Expected:\n%s\ngot\n%s", assetOutput, body) + if strings.TrimSpace(string(body)) != assetOutput { + t.Fatalf("Expected:\n%s\ngot\n%s", assetOutput, string(body)) } })) defer es.Close() @@ -90,6 +90,41 @@ func TestProxyHandlerError(t *testing.T) { }) } +func TestProxyHandlerVariables(t *testing.T) { + endpointServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + if strings.TrimSpace(string(body)) != variableAssetOutput { + t.Fatalf("Expected:\n%s\ngot\n%s", variableAssetOutput, body) + } + })) + defer endpointServer.Close() + + schema := []byte(assetSchema) + backendURL, err := url.Parse(endpointServer.URL) + if err != nil { + t.Fatal(err) + } + + requestConfigProvider := proxy.NewStaticRequestConfigProvider(proxy.RequestConfig{ + Schema: &schema, + BackendURL: *backendURL, + }) + + proxyHandler := NewDefaultProxy(requestConfigProvider, &hackmiddleware.AssetUrlMiddleware{}) + testServer := httptest.NewServer(proxyHandler) + defer testServer.Close() + + t.Run("Test proxy handler", func(t *testing.T) { + _, err := http.Post(testServer.URL, "application/graphql", strings.NewReader(variableAssetInput)) + if err != nil { + t.Error(err) + } + }) +} + func BenchmarkProxyHandler(b *testing.B) { //go printMemUsage() @@ -173,7 +208,8 @@ type Asset implements Node { url: String! }` -const assetInput = `{"query":"query testQueryWithoutHandle {assets(first: 1) { id fileName url(transformation: {image: {resize: {width: 100, height: 100}}})}}"}` +const assetInput = `{"query":"query testQueryWithoutHandle {assets(first:1) { id fileName url(transformation: {image: {resize: {width: 100, height: 100}}})}}"}` +const assetOutput = `{"query":"query testQueryWithoutHandle {assets(first:1) {id fileName handle}}"}` -const assetOutput = `{"query":"query testQueryWithoutHandle {assets(first:1) {id fileName handle}}"} -` +const variableAssetInput = `{"query":"query testQueryWithoutHandle {assets(first: 1) { id fileName url(transformation: {image: {resize: {width: 100, height: 100}}})}}","variables":{"id":1}}` +const variableAssetOutput = `{"query":"query testQueryWithoutHandle {assets(first:1) {id fileName handle}}","variables":{"id":1}}`