From 689b1efc437c57ae354262d260e037ad1fae8ee7 Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Sat, 8 Apr 2023 00:54:48 +0100 Subject: [PATCH] Bugfixes + ability to set values per query. --- README.md | 6 +++++- base.go | 6 ++++-- base_test.go | 30 +++++++++++++++++++++++++++++- go.sum | 8 -------- query.go | 30 ++++++++++++++++++++++++++++++ query_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ request.go | 2 +- 7 files changed, 119 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ddea6e1..9b23929 100644 --- a/README.md +++ b/README.md @@ -46,13 +46,17 @@ You have two options to enable the cache: * Use `GRAPHQL_CACHE_ENABLED` environment variable which will enable the cache globally. It may be desired if you want to use the cache for all queries. * Add `gqlcache: true` header for your query which will enable the cache for this query only with `GRAPHQL_CACHE_TTL` TTL. +* You can check the list of supported per-query modifiers below Example: ```go +// following values passed as headers will modify behaviour of the query +// and disregard settings provided via environment variables headers := map[string]interface{}{ ... - "gqlcache": true, + "gqlcache": true, // sets the cache as on for this query only + "gqlretries": false, // disables retries for this query only } ``` diff --git a/base.go b/base.go index 59c4fa8..efc493c 100644 --- a/base.go +++ b/base.go @@ -30,8 +30,6 @@ func NewConnection() *BaseClient { if b.LoggerWriter == nil { b.LoggerWriter = log.New(os.Stdout, "", log.LstdFlags) - } else { - b.LoggerWriter = b.LoggerWriter } b.endpoint = envutil.Getenv("GRAPHQL_ENDPOINT", "https://api.github.com/graphql") @@ -96,3 +94,7 @@ func NewConnection() *BaseClient { b.Logger.Info(b, "graphQL client initialized;") return b } + +func (b *BaseClient) SetEndpoint(endpoint string) { + b.endpoint = endpoint +} diff --git a/base_test.go b/base_test.go index 55e9c13..4ab7fad 100644 --- a/base_test.go +++ b/base_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/lukaszraczylo/go-simple-graphql/utils/logger" - "github.com/stretchr/testify/assert" ) @@ -101,3 +100,32 @@ func TestNewConnectionLogLevels(t *testing.T) { }) } } + +func TestBaseClient_SetEndpoint(t *testing.T) { + type fields struct { + } + type args struct { + endpoint string + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "Test SetEndpoint", + args: args{ + endpoint: "https://potato/graphql", + }, + want: "https://potato/graphql", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := NewConnection() + b.SetEndpoint(tt.args.endpoint) + assert.Equal(t, tt.want, b.endpoint) + }) + } +} diff --git a/go.sum b/go.sum index ed859af..c8ea705 100644 --- a/go.sum +++ b/go.sum @@ -42,22 +42,14 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4= golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/query.go b/query.go index 1898497..12fd34d 100644 --- a/query.go +++ b/query.go @@ -2,6 +2,9 @@ package gql import ( "context" + "fmt" + "reflect" + "strconv" "github.com/lukaszraczylo/go-simple-graphql/utils/helpers" @@ -71,6 +74,13 @@ func (c *BaseClient) Query(queryContent string, queryVariables interface{}, quer var queryHash string var cachedResponse []byte + var cacheBaseClient BaseClient + + // Check for library specific headers + if len(queryHeaders) > 0 { + cacheBaseClient = reflect.ValueOf(*c).Interface().(BaseClient) + queryHeaders = c.parseQueryHeaders(queryHeaders) + } if c.cache.enabled { queryHash = strutil.Md5(query.compiledQuery) @@ -101,6 +111,10 @@ func (c *BaseClient) Query(queryContent string, queryVariables interface{}, quer c.cache.client.Set(queryHash, jsonData) } + if len(queryHeaders) > 0 { + *c = cacheBaseClient + } + return c.decodeResponse(jsonData), err } @@ -115,3 +129,19 @@ func (c *BaseClient) decodeResponse(jsonData []byte) any { return nil } } + +func (c *BaseClient) parseQueryHeaders(queryHeaders map[string]interface{}) (returnHeaders map[string]interface{}) { + returnHeaders = make(map[string]interface{}) + for k, v := range queryHeaders { + if k == "gqlcache" { + c.cache.enabled, _ = strconv.ParseBool(fmt.Sprintf("%v", v)) + continue + } + if k == "gqlretries" { + c.retries.enabled, _ = strconv.ParseBool(fmt.Sprintf("%v", v)) + continue + } + returnHeaders[k] = v + } + return returnHeaders +} diff --git a/query_test.go b/query_test.go index 966cefe..f4c4524 100644 --- a/query_test.go +++ b/query_test.go @@ -289,3 +289,53 @@ func BenchmarkQueryWithCache(b *testing.B) { }`, nil, nil) } } + +func TestBaseClient_parseQueryHeaders(t *testing.T) { + type fields struct { + } + type args struct { + queryHeaders map[string]interface{} + } + tests := []struct { + name string + fields fields + args args + wantReturnHeaders map[string]interface{} + }{ + { + name: "Test parseQueryHeaders - no change", + fields: fields{}, + args: args{ + queryHeaders: map[string]interface{}{ + "x-test-header": "test", + "x-test-header-next": true, + }, + }, + wantReturnHeaders: map[string]interface{}{ + "x-test-header": "test", + "x-test-header-next": true, + }, + }, + { + name: "Test parseQueryHeaders - lib-headers removed", + fields: fields{}, + args: args{ + queryHeaders: map[string]interface{}{ + "x-test-header": "test", + "gqlcache": true, + }, + }, + wantReturnHeaders: map[string]interface{}{ + "x-test-header": "test", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := NewConnection() + if gotReturnHeaders := c.parseQueryHeaders(tt.args.queryHeaders); !reflect.DeepEqual(gotReturnHeaders, tt.wantReturnHeaders) { + t.Errorf("BaseClient.parseQueryHeaders() = %v, want %v", gotReturnHeaders, tt.wantReturnHeaders) + } + }) + } +} diff --git a/request.go b/request.go index a3a4604..e5166a2 100644 --- a/request.go +++ b/request.go @@ -18,7 +18,7 @@ func (c *BaseClient) executeQuery(query []byte, headers any) (result any, err er } for key, value := range headers.(map[string]interface{}) { - httpRequest.Header.Add(key, value.(string)) + httpRequest.Header.Add(key, fmt.Sprintf("%s", value)) } var httpResponse *http.Response