Skip to content

Commit

Permalink
improve the performance of applying the query parameters
Browse files Browse the repository at this point in the history
* improve the loging by adding the query parameters from the request first, then adding the parameters from the client and skip if already exists
* additional unit tests for the query parameters

```shell
% go test -benchmem -bench=. -run=^Benchmark
goos: darwin
goarch: amd64
pkg: github.com/go-resty/resty/v2
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Benchmark_parseRequestURL_QueryParams-16          800851              1490 ns/op             400 B/op          9 allocs/op
PASS
ok      github.com/go-resty/resty/v2    2.473s
```
  • Loading branch information
SVilgelm committed Sep 25, 2023
1 parent b7305a9 commit f13ee9a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
41 changes: 20 additions & 21 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,32 +134,31 @@ func parseRequestURL(c *Client, r *Request) error {
}

// Adding Query Param
query := make(url.Values)
for k, v := range c.QueryParam {
for _, iv := range v {
query.Add(k, iv)
if l := len(c.QueryParam) + len(r.QueryParam); l > 0 {
query := make(url.Values, l)
for k, v := range r.QueryParam {
query[k] = v[:]
}
}

for k, v := range r.QueryParam {
// remove query param from client level by key
// since overrides happens for that key in the request
query.Del(k)
for k, v := range c.QueryParam {
// skip query parameter if it was set from request
if _, ok := query[k]; ok {
continue
}

for _, iv := range v {
query.Add(k, iv)
query[k] = v[:]
}
}

// GitHub #123 Preserve query string order partially.
// Since not feasible in `SetQuery*` resty methods, because
// standard package `url.Encode(...)` sorts the query params
// alphabetically
if len(query) > 0 {
if IsStringEmpty(reqURL.RawQuery) {
reqURL.RawQuery = query.Encode()
} else {
reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode()
// GitHub #123 Preserve query string order partially.
// Since not feasible in `SetQuery*` resty methods, because
// standard package `url.Encode(...)` sorts the query params
// alphabetically
if len(query) > 0 {
if IsStringEmpty(reqURL.RawQuery) {
reqURL.RawQuery = query.Encode()
} else {
reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode()
}
}
}

Expand Down
21 changes: 20 additions & 1 deletion middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,32 @@ func Test_parseRequestURL(t *testing.T) {
"foo": "1", // ignored, because of the "foo" parameter in request
"bar": "2",
})
c.SetQueryParams(map[string]string{
r.SetQueryParams(map[string]string{
"foo": "3",
})
r.URL = "https://example.com/"
},
expectedURL: "https://example.com/?foo=3&bar=2",
},
{
name: "adding query parameters by request to URL with existent",
init: func(c *Client, r *Request) {
r.SetQueryParams(map[string]string{
"bar": "2",
})
r.URL = "https://example.com/?foo=1"
},
expectedURL: "https://example.com/?foo=1&bar=2",
},
{
name: "adding query parameters by request with multiple values",
init: func(c *Client, r *Request) {
r.QueryParam.Add("foo", "1")
r.QueryParam.Add("foo", "2")
r.URL = "https://example.com/"
},
expectedURL: "https://example.com/?foo=1&foo=2",
},
} {
t.Run(tt.name, func(t *testing.T) {
c := New()
Expand Down

0 comments on commit f13ee9a

Please sign in to comment.