Compare commits

...
24 Commits
Author SHA1 Message Date
lukaszraczylo a5c4643a5e Update dependencies and use realigned structs. 2023-03-31 15:31:42 +01:00
lukaszraczylo 42e1afbf77 Fix the ancient bug where client wasn't able to use non-https endpoints. 2023-02-26 11:38:20 +00:00
lukaszraczylo 9e8df7e297 Clean the dependencies. 2023-02-26 10:53:38 +00:00
lukaszraczylo 405d159eb9 Use dialer to automagically pick between https and http endpoints. 2023-02-26 10:53:06 +00:00
lukaszraczylo b3e594fc4f Update documentation. 2023-02-03 15:59:44 +00:00
lukaszraczylo 32d9e0bd80 Update dependencies. 2023-02-02 10:38:48 +00:00
lukaszraczylo e706b07488 fixup! Add cache per query. 2022-12-20 10:30:04 +00:00
lukaszraczylo 32091fc8cd Add cache per query. 2022-12-20 10:26:05 +00:00
lukaszraczylo edc695fe2b Update dependencies. 2022-12-19 11:25:18 +00:00
lukaszraczylo bd0c5ec373 Update logging package to bring a bit of a speed improvement. 2022-12-19 11:22:58 +00:00
lukaszraczylo 952749d7ff Update dependencies, switch got avast retry. 2022-12-05 12:22:12 +00:00
lukaszraczylo 277ef21263 fixup! Update dependencies. 2022-12-05 12:09:42 +00:00
lukaszraczylo 4980aeb28a Update dependencies. 2022-12-05 11:58:28 +00:00
lukaszraczylo 91f65ebd46 Update dependencies. 2022-10-17 14:47:28 +01:00
lukaszraczylo d5655ae2fa Well.. This escalated quickly. 2022-06-08 19:33:34 +01:00
lukaszraczylo 9b65ba069f Change retry library to something more useful. 2022-06-08 19:07:26 +01:00
lukaszraczylo feed2f36c2 fixup! fixup! fixup! fixup! fixup! Add retries functionality. 2022-06-08 17:36:47 +01:00
lukaszraczylo 966d9ccd0a fixup! fixup! fixup! fixup! Add retries functionality. 2022-06-08 15:51:29 +01:00
lukaszraczylo 3232498e94 fixup! fixup! fixup! Add retries functionality. 2022-06-08 15:42:28 +01:00
lukaszraczylo 3cda8e267b fixup! fixup! Add retries functionality. 2022-06-08 15:40:49 +01:00
lukaszraczylo 1393f4d7cf fixup! Add retries functionality. 2022-06-08 13:48:09 +01:00
lukaszraczylo d4328fdbb7 Add retries functionality. 2022-06-08 13:25:06 +01:00
lukaszraczylo 4ac9f132a2 Update dependencies. 2022-05-28 01:09:53 +01:00
lukaszraczylo fb04e68b8d Update dependencies. 2022-05-27 22:47:38 +01:00
8 changed files with 350 additions and 176 deletions
+49 -21
View File
@@ -9,7 +9,9 @@ Ps. It's Hasura friendly.
- [Features](#features) - [Features](#features)
- [Usage example](#usage-example) - [Usage example](#usage-example)
- [Environment variables](#environment-variables) - [Environment variables](#environment-variables)
- [Cache](#cache)
- [Example reader code](#example-reader-code) - [Example reader code](#example-reader-code)
- [Tips](#tips)
- [Working with results](#working-with-results) - [Working with results](#working-with-results)
## Reasoning ## Reasoning
@@ -33,6 +35,25 @@ Therefore, I present you the simple client to which you can copy & paste your gr
* `GRAPHQL_CACHE` - Should the query cache be enabled? Default: `false` * `GRAPHQL_CACHE` - Should the query cache be enabled? Default: `false`
* `GRAPHQL_CACHE_TTL` - Cache TTL in seconds for SELECT type of queries. Default: `5` * `GRAPHQL_CACHE_TTL` - Cache TTL in seconds for SELECT type of queries. Default: `5`
* `LOG_LEVEL` - Logging level. Default: `info` * `LOG_LEVEL` - Logging level. Default: `info`
* `RETRIES_ENABLE` - Should retries be enabled? Default: `false`
* `RETRIES_NUMBER` - Number of retries: Default: `1`
* `RETRIES_DELAY` - Delay in retries in milliseconds. Default: `250`
### Cache
You have two options to enable the cache:
* Use `GRAPHQL_CACHE` 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.
Example:
```go
headers := map[string]interface{}{
...
"gqlcache": true,
}
```
### Example reader code ### Example reader code
@@ -43,32 +64,39 @@ import (
graphql "github.com/lukaszraczylo/go-simple-graphql" graphql "github.com/lukaszraczylo/go-simple-graphql"
) )
headers := map[string]interface{}{ func main() {
"x-hasura-user-id": 37, headers := map[string]interface{}{
"x-hasura-user-uuid": "bde1962e-b42e-1212-ac10-d43fa27f44a5", "x-hasura-user-id": 37,
} "x-hasura-user-uuid": "bde1962e-b42e-1212-ac10-d43fa27f44a5",
variables := map[string]interface{}{
"fileHash": "123deadc0w321",
}
query := `query searchFileKnown($fileHash: String) {
tbl_file_scans(where: {file_hash: {_eq: $fileHash}}) {
racy
violence
virus
} }
}`
gql := graphql.NewConnection() variables := map[string]interface{}{
result, err := gql.Query(query, variables, headers) "fileHash": "123deadc0w321",
if err != nil { }
fmt.Println("Query error", err)
return query := `query searchFileKnown($fileHash: String) {
tbl_file_scans(where: {file_hash: {_eq: $fileHash}}) {
racy
violence
virus
}
}`
gql := graphql.NewConnection()
result, err := gql.Query(query, variables, headers)
if err != nil {
fmt.Println("Query error", err)
return
}
fmt.Println(result)
} }
fmt.Println(result)
``` ```
### Tips
* Connection handler ( `gql := graphql.NewConnection()` ) should be created once and reused in the application especially if you run dozens of queries per second. It will allow you also to use cache and http2 to its full potential.
**Result** **Result**
```json ```json
+18 -11
View File
@@ -1,25 +1,32 @@
module github.com/lukaszraczylo/go-simple-graphql module github.com/lukaszraczylo/go-simple-graphql
go 1.17 go 1.20
require ( require (
github.com/allegro/bigcache/v3 v3.0.2 github.com/allegro/bigcache/v3 v3.1.0
github.com/avast/retry-go v3.0.0+incompatible
github.com/buger/jsonparser v1.1.1 github.com/buger/jsonparser v1.1.1
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/lukaszraczylo/pandati v0.0.12 github.com/lukaszraczylo/pandati v0.0.20
github.com/rs/zerolog v1.26.1 github.com/rs/zerolog v1.29.0
github.com/stretchr/testify v1.7.0 github.com/sethvargo/go-retry v0.2.4
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 github.com/stretchr/testify v1.7.1
golang.org/x/net v0.8.0
) )
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/imdario/mergo v0.3.12 // indirect github.com/imdario/mergo v0.3.15 // indirect
github.com/kr/pretty v0.1.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/text v0.3.7 // indirect github.com/tidwall/gjson v1.14.4 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect github.com/tidwall/match v1.1.1 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect github.com/tidwall/pretty v1.2.1 // indirect
github.com/wI2L/jsondiff v0.3.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )
+46 -63
View File
@@ -1,28 +1,30 @@
github.com/allegro/bigcache/v3 v3.0.1 h1:Q4Xl3chywXuJNOw7NV+MeySd3zGQDj4KCpkCg0te8mc= github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk=
github.com/allegro/bigcache/v3 v3.0.1/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I= github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
github.com/allegro/bigcache/v3 v3.0.2 h1:AKZCw+5eAaVyNTBmI2fgyPVJhHkdWder3O9IrprcQfI= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
github.com/allegro/bigcache/v3 v3.0.2/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/lukaszraczylo/pandati v0.0.18 h1:6khtDY6QXkiyh4a3dzHtIzx/9UqUGfHjzKBCA0SIurI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/lukaszraczylo/pandati v0.0.18/go.mod h1:Aqlc0KH+ssvrscYYbEKMv7n5cFwe+0MjsJbikNz1h60=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/lukaszraczylo/pandati v0.0.20 h1:LqF7CS3z9Zi04KwEY8wd/YUpfWKSwi0nc7pagKQLXHc=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/lukaszraczylo/pandati v0.0.20/go.mod h1:ZegK9ll9UebKV1uNMF73qdLb43G/O4CSOdPglu6NniQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/lukaszraczylo/pandati v0.0.10 h1:ZXmLjxb/UYRBVyAKwXmUcJgZ2FYNwGY4YDJsQQMYAXI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/lukaszraczylo/pandati v0.0.10/go.mod h1:1lE/x4X4LfO1yerAQoiR7AVb/wIabH/zITDGnqTdyH8= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/lukaszraczylo/pandati v0.0.12 h1:WPQM36t7tjaIe4eUtEpw5HZ8bm/KtHrVQA/T74Em1zU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/lukaszraczylo/pandati v0.0.12/go.mod h1:1lE/x4X4LfO1yerAQoiR7AVb/wIabH/zITDGnqTdyH8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -31,54 +33,35 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec=
github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= github.com/wI2L/jsondiff v0.3.0 h1:iTzQ9u/d86GE9RsBzVHX88f2EA1vQUboHwLhSQFc1s4=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= github.com/wI2L/jsondiff v0.3.0/go.mod h1:y1IMzNNjlSsk3IUoJdRJO7VRBtzMvRgyo4Vu0LdHpTc=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+69 -22
View File
@@ -18,11 +18,13 @@ import (
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/allegro/bigcache/v3" bigcache "github.com/allegro/bigcache/v3"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/lukaszraczylo/go-simple-graphql/pkg/logging" "github.com/lukaszraczylo/go-simple-graphql/pkg/logging"
retry "github.com/sethvargo/go-retry"
"golang.org/x/net/http2" "golang.org/x/net/http2"
) )
@@ -31,11 +33,15 @@ var (
) )
type GraphQL struct { type GraphQL struct {
Endpoint string BackoffSetup retry.Backoff
HttpClient *http.Client HttpClient *http.Client
Log *logging.LogConfig Log *logging.LogConfig
Cache bool // Enable caching for read queries CacheStore *bigcache.BigCache
CacheStore *bigcache.BigCache Endpoint string
RetriesNumber int
RetriesDelay time.Duration
Cache bool
RetriesEnable bool
} }
func pickGraphqlEndpoint() (graphqlEndpoint string) { func pickGraphqlEndpoint() (graphqlEndpoint string) {
@@ -76,23 +82,64 @@ func setCacheEnabled() bool {
} }
func NewConnection() *GraphQL { func NewConnection() *GraphQL {
g := GraphQL{
Endpoint: pickGraphqlEndpoint(), endpoint := pickGraphqlEndpoint()
HttpClient: &http.Client{ var httpClient *http.Client
Transport: &http2.Transport{ if strings.HasPrefix(endpoint, "http://") {
ReadIdleTimeout: 30 * time.Second, // HTTP/1.1 client
DisableCompression: false, httpClient = &http.Client{}
AllowHTTP: true, } else {
PingTimeout: 10 * time.Second, // HTTP/2 or HTTPS client
TLSClientConfig: &tls.Config{ http2Transport := &http2.Transport{
InsecureSkipVerify: true, AllowHTTP: true,
}, }
}, if strings.HasPrefix(endpoint, "https://") {
}, http2Transport.TLSClientConfig = &tls.Config{
Log: logging.NewLogger(), InsecureSkipVerify: true,
Cache: setCacheEnabled(), }
CacheStore: setupCache(), }
httpClient = &http.Client{
Transport: http2Transport,
}
} }
g := GraphQL{
Endpoint: endpoint,
HttpClient: httpClient,
Log: logging.NewLogger(),
Cache: setCacheEnabled(),
CacheStore: setupCache(),
RetriesEnable: false,
RetriesNumber: 1,
RetriesDelay: 250,
BackoffSetup: nil,
}
var err error
retriesEnable, retriesEnableExists := os.LookupEnv("RETRIES_ENABLE")
if retriesEnableExists {
g.RetriesEnable, err = strconv.ParseBool(retriesEnable)
if err != nil {
panic("Invalid value for RETRIES_ENABLE")
}
retriesNumber, retriesNumberExists := os.LookupEnv("RETRIES_NUMBER")
if retriesNumberExists {
g.RetriesNumber, err = strconv.Atoi(retriesNumber)
if err != nil {
panic("Invalid value for RETRIES_NUMBER")
}
}
retriesDelay, retriesDelayExists := os.LookupEnv("RETRIES_DELAY")
if retriesDelayExists {
retDel, err := strconv.Atoi(retriesDelay)
if err != nil {
panic("Invalid value for RETRIES_DELAY")
}
g.RetriesDelay = time.Duration(retDel) * time.Millisecond
}
}
g.BackoffSetup = retry.NewExponential(g.RetriesDelay)
g.BackoffSetup = retry.WithMaxRetries(uint64(g.RetriesNumber), g.BackoffSetup)
return &g return &g
} }
+1 -1
View File
@@ -35,9 +35,9 @@ func (suite *TestSuite) TestNewConnection() {
endpoint string endpoint string
} }
tests := []struct { tests := []struct {
want *GraphQL
name string name string
args args args args
want *GraphQL
}{ }{
{ {
name: "New connection: Env variable endpoint", name: "New connection: Env variable endpoint",
+4 -4
View File
@@ -82,9 +82,9 @@ func (suite *LoggingTestSuite) TestLogConfig_AllHandlers() {
wantLevel string wantLevel string
wantMessage string wantMessage string
envMinLogLevel string envMinLogLevel string
loggerType string
stdOutExpect bool stdOutExpect bool
stdErrExpect bool stdErrExpect bool
loggerType string
}{ }{
{ {
name: "Test log: Error", name: "Test log: Error",
@@ -232,21 +232,21 @@ func (suite *LoggingTestSuite) TestLogConfig_AllHandlers() {
func (suite *LoggingTestSuite) TestFullMessage() { func (suite *LoggingTestSuite) TestFullMessage() {
type args struct { type args struct {
message string
extraFields map[string]interface{} extraFields map[string]interface{}
message string
} }
extraFields := make(map[string]interface{}) extraFields := make(map[string]interface{})
extraFields["_full_message"] = "full message" extraFields["_full_message"] = "full message"
tests := []struct { tests := []struct {
name string
args args args args
name string
wantLevel string wantLevel string
wantMessage string wantMessage string
envMinLogLevel string envMinLogLevel string
loggerType string
stdOutExpect bool stdOutExpect bool
stdErrExpect bool stdErrExpect bool
loggerType string
}{ }{
{ {
name: "Test log: Error", name: "Test log: Error",
+44 -21
View File
@@ -5,16 +5,16 @@ import (
"crypto/md5" "crypto/md5"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
retry "github.com/avast/retry-go"
"github.com/lukaszraczylo/pandati" "github.com/lukaszraczylo/pandati"
) )
type requestBase struct { type requestBase struct {
Query string `json:"query"`
Variables interface{} `json:"variables"` Variables interface{} `json:"variables"`
Query string `json:"query"`
} }
type queryResults struct { type queryResults struct {
@@ -50,6 +50,12 @@ func (g *GraphQL) Query(queryContent string, queryVariables interface{}, queryHe
var queryResult *queryResults var queryResult *queryResults
queryHash := fmt.Sprintf("%x", md5.Sum(query)) queryHash := fmt.Sprintf("%x", md5.Sum(query))
// If header 'gqlcache' is set to true, we will enforce the cache for the query
if !pandati.IsZero(queryHeaders) && !pandati.IsZero(queryHeaders["gqlcache"]) && queryHeaders["gqlcache"].(bool) {
g.Log.Debug("Forced cache for query", map[string]interface{}{"_query": queryContent, "_headers": queryHeaders})
g.Cache = true
}
if g.Cache { if g.Cache {
g.Log.Debug("Checking the cache for the query", map[string]interface{}{"_query": queryHash}) g.Log.Debug("Checking the cache for the query", map[string]interface{}{"_query": queryHash})
if entry, entryInfo, err := g.CacheStore.GetWithInfo(queryHash); err == nil { if entry, entryInfo, err := g.CacheStore.GetWithInfo(queryHash); err == nil {
@@ -63,34 +69,51 @@ func (g *GraphQL) Query(queryContent string, queryVariables interface{}, queryHe
} }
httpRequest, err := http.NewRequest("POST", g.Endpoint, bytes.NewBuffer(query)) httpRequest, err := http.NewRequest("POST", g.Endpoint, bytes.NewBuffer(query))
//httpRequest.Header.Add("Content-Type", "application/json") // httpRequest.Header.Set("Content-Type", "application/json")
if err != nil {
g.Log.Error("Unable to create the request", map[string]interface{}{"_error": err.Error()})
return "", err
}
for header, value := range queryHeaders { for header, value := range queryHeaders {
httpRequest.Header.Add(fmt.Sprintf("%v", header), fmt.Sprintf("%v", value)) httpRequest.Header.Add(fmt.Sprintf("%v", header), fmt.Sprintf("%v", value))
} }
httpResponse, err := g.HttpClient.Do(httpRequest) var httpResponse *http.Response
if err != nil {
g.Log.Error("Unable to send the query", map[string]interface{}{"_error": err.Error()})
return "", err
}
defer io.Copy(ioutil.Discard, httpResponse.Body)
defer httpResponse.Body.Close()
body, err = ioutil.ReadAll(httpResponse.Body) err = retry.Do(
if err != nil { func() error {
g.Log.Critical("Unable to read the response", map[string]interface{}{"_error": err.Error()}) g.Log.Debug("Sending the query")
return "", err httpResponse, err = g.HttpClient.Do(httpRequest)
}
err = json.Unmarshal(body, &queryResult) if err != nil {
if err != nil { g.Log.Debug("Unable to send the query RETRY", map[string]interface{}{"_error": err.Error()})
g.Log.Error("Unable to unmarshal the query", map[string]interface{}{"_error": err.Error()}) return err
return "", err }
} defer httpResponse.Body.Close()
if httpResponse.StatusCode <= 200 && httpResponse.StatusCode >= 204 {
return err
}
body, err = ioutil.ReadAll(httpResponse.Body)
if err != nil {
g.Log.Debug("Unable to read the response", map[string]interface{}{"_error": err.Error()})
return err
}
err = json.Unmarshal(body, &queryResult)
if err != nil {
g.Log.Debug("Unable to unmarshal the query", map[string]interface{}{"_error": err.Error()})
return err
}
return nil
},
)
if !pandati.IsZero(queryResult.Errors) { if !pandati.IsZero(queryResult.Errors) {
g.Log.Error("Query returned error", map[string]interface{}{"_query": queryContent, "_variables": queryVariables, "_error": fmt.Sprintf("%v", queryResult.Errors), "_response_code": httpResponse.StatusCode}) g.Log.Error("Query returned error", map[string]interface{}{"_query": queryContent, "_variables": queryVariables, "_error": fmt.Sprintf("%v", queryResult.Errors), "_response_code": httpResponse.StatusCode})
return "", fmt.Errorf("%v", queryResult.Errors[0].Message) return "", fmt.Errorf("%v", queryResult.Errors)
} }
if pandati.IsZero(queryResult.Data) { if pandati.IsZero(queryResult.Data) {
+119 -33
View File
@@ -11,8 +11,8 @@ import (
func (suite *TestSuite) Test_GraphQL_queryBuilder() { func (suite *TestSuite) Test_GraphQL_queryBuilder() {
type args struct { type args struct {
queryContent string
queryVariables interface{} queryVariables interface{}
queryContent string
} }
tests := []struct { tests := []struct {
name string name string
@@ -26,7 +26,7 @@ func (suite *TestSuite) Test_GraphQL_queryBuilder() {
queryContent: `query listUserBots { tbl_bots { bot_name } }`, queryContent: `query listUserBots { tbl_bots { bot_name } }`,
queryVariables: nil, queryVariables: nil,
}, },
want: []byte(`{"query":"query listUserBots { tbl_bots { bot_name } }","variables":null}`), want: []byte(`{"variables":null,"query":"query listUserBots { tbl_bots { bot_name } }"}`),
wantErr: false, wantErr: false,
}, },
{ {
@@ -35,7 +35,7 @@ func (suite *TestSuite) Test_GraphQL_queryBuilder() {
queryContent: `query listUserBots { tbl_bots { bot_name } }`, queryContent: `query listUserBots { tbl_bots { bot_name } }`,
queryVariables: map[string]interface{}{"user_id": 1}, queryVariables: map[string]interface{}{"user_id": 1},
}, },
want: []byte(`{"query":"query listUserBots { tbl_bots { bot_name } }","variables":{"user_id":1}}`), want: []byte(`{"variables":{"user_id":1},"query":"query listUserBots { tbl_bots { bot_name } }"}`),
wantErr: false, wantErr: false,
}, },
} }
@@ -58,75 +58,163 @@ func (suite *TestSuite) Test_GraphQL_Query() {
g := NewConnection() g := NewConnection()
type args struct { type args struct {
queryContent string
queryVariables interface{} queryVariables interface{}
queryHeaders map[string]interface{} queryHeaders map[string]interface{}
queryContent string
} }
tests := []struct { tests := []struct {
args args
name string name string
endpoint string endpoint string
wantResult string
isLocal bool isLocal bool
cache_enabled bool cache_enabled bool
args args
wantResult string
wantErr bool wantErr bool
}{ }{
{ {
name: "Valid query, no cache", name: "Valid query, no cache",
endpoint: "https://hasura.local/v1/graphql", endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true, isLocal: true,
cache_enabled: false, cache_enabled: false,
args: args{ args: args{
queryContent: `query listUserBots { queryContent: `query packages_prices {
tbl_bots(limit: 1) { sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
bot_name aggregate {
count
}
} }
}`, }`,
queryVariables: nil, queryVariables: nil,
}, },
wantResult: `{"tbl_bots":[{"bot_name":"ThetaGuardianBot"}]}`, wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false,
},
{
name: "Valid query, no cache #2",
endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true,
cache_enabled: false,
args: args{
queryContent: `query packages_prices {
sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
aggregate {
count
}
}
}`,
queryVariables: nil,
},
wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false, wantErr: false,
}, },
{ {
name: "Valid query, with cache empty", name: "Valid query, with cache empty",
endpoint: "https://hasura.local/v1/graphql", endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true, isLocal: true,
cache_enabled: true, cache_enabled: true,
args: args{ args: args{
queryContent: `query listUserBots { queryContent: `query packages_prices {
tbl_bots(limit: 1) { sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
bot_name aggregate {
count
}
} }
}`, }`,
queryVariables: nil, queryVariables: nil,
}, },
wantResult: `{"tbl_bots":[{"bot_name":"ThetaGuardianBot"}]}`, wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false,
},
{
name: "Valid query, with cache per query empty",
endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true,
cache_enabled: false,
args: args{
queryContent: `query packages_prices_no_inlinecache {
sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
aggregate {
count
}
}
}`,
queryVariables: nil,
queryHeaders: map[string]interface{}{
"gqlcache": false,
},
},
wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false,
},
{
name: "Valid query, with cache per query",
endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true,
cache_enabled: false,
args: args{
queryContent: `query packages_prices_inlinecache {
sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
aggregate {
count
}
}
}`,
queryVariables: nil,
queryHeaders: map[string]interface{}{
"gqlcache": true,
},
},
wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false,
},
{
name: "Valid query, with cache per query [verify]",
endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true,
cache_enabled: false,
args: args{
queryContent: `query packages_prices_inlinecache {
sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
aggregate {
count
}
}
}`,
queryVariables: nil,
queryHeaders: map[string]interface{}{
"gqlcache": true,
},
},
wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false, wantErr: false,
}, },
{ {
name: "Valid query, with cache filled", name: "Valid query, with cache filled",
endpoint: "https://hasura.local/v1/graphql", endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true, isLocal: true,
cache_enabled: true, cache_enabled: true,
args: args{ args: args{
queryContent: `query listUserBots { queryContent: `query packages_prices {
tbl_bots(limit: 1) { sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
bot_name aggregate {
count
}
} }
}`, }`,
queryVariables: nil, queryVariables: nil,
}, },
wantResult: `{"tbl_bots":[{"bot_name":"ThetaGuardianBot"}]}`, wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false, wantErr: false,
}, },
{ {
name: "Invalid query", name: "Invalid query",
endpoint: "https://hasura.local/v1/graphql", endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: true, isLocal: true,
args: args{ args: args{
queryContent: `query listUserBots { queryContent: `query packages_pricez {
tbl_botz(limit: 1) { sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
bot_name aggregate {
count
} }
}`, }`,
queryVariables: nil, queryVariables: nil,
@@ -136,21 +224,19 @@ func (suite *TestSuite) Test_GraphQL_Query() {
}, },
{ {
name: "Valid query to https endpoint", name: "Valid query to https endpoint",
endpoint: "https://web-dev.telegram-bot.app/v1/graphql", endpoint: "https://telegram-bot.app/v1/graphql",
isLocal: false, isLocal: false,
args: args{ args: args{
queryContent: `query packages_prices { queryContent: `query packages_prices {
available_packages: tbl_available_packages(where: {enabled: {_eq: true}}) { sub_group_packages_aggregate(where: {enabled: {_eq: true}}) {
package_name aggregate {
package_discount count
package_price }
package_size
package_type
} }
}`, }`,
queryVariables: nil, queryVariables: nil,
}, },
wantResult: `{"available_packages":[{"package_discount":0,"package_name":"media_1000","package_price":750,"package_size":1000,"package_type":"media"},{"package_discount":5,"package_name":"media_5000","package_price":3563,"package_size":5000,"package_type":"media"},{"package_discount":10,"package_name":"media_10000","package_price":6750,"package_size":10000,"package_type":"media"},{"package_discount":15,"package_name":"media_25000","package_price":15938,"package_size":25000,"package_type":"media"},{"package_discount":0,"package_name":"voice_500","package_price":1000,"package_size":500,"package_type":"voice"},{"package_discount":10,"package_name":"voice_1000","package_price":1800,"package_size":1000,"package_type":"voice"},{"package_discount":15,"package_name":"voice_2500","package_price":4250,"package_size":2500,"package_type":"voice"}]}`, wantResult: `{"sub_group_packages_aggregate":{"aggregate":{"count":4}}}`,
wantErr: false, wantErr: false,
}, },
{ {