Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add request funcs method for request composition #910

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ type (
// SuccessHook type is for reacting to request success
SuccessHook func(*Client, *Response)

// RequestFunc type is for extended manipulation of the Request instance
RequestFunc func(*Request) *Request

// TLSClientConfiger interface is to configure TLS Client configuration on custom transport
// implemented using [http.RoundTripper]
TLSClientConfiger interface {
Expand Down
27 changes: 27 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,33 @@ func (r *Request) Clone(ctx context.Context) *Request {
return rr
}

// Funcs method gets executed on request composition that passes the
// current request instance to provided [RequestFunc], which could be
// used to apply common/reusable logic to the given request instance.
//
// func addRequestContentType(r *Request) *Request {
// return r.SetHeader("Content-Type", "application/json").
// SetHeader("Accept", "application/json")
// }
//
// func addRequestQueryParams(page, size int) func(r *Request) *Request {
// return func(r *Request) *Request {
// return r.SetQueryParam("page", strconv.Itoa(page)).
// SetQueryParam("size", strconv.Itoa(size)).
// SetQueryParam("request_no", strconv.Itoa(int(time.Now().Unix())))
// }
// }
//
// client.R().
// Funcs(addRequestContentType, addRequestQueryParams(1, 100)).
// Get("https://localhost:8080/foobar")
func (r *Request) Funcs(funcs ...RequestFunc) *Request {
for _, f := range funcs {
r = f(r)
}
return r
}

func (r *Request) fmtBodyString(sl int) (body string) {
body = "***** NO CONTENT *****"
if !r.isPayloadSupported() {
Expand Down
34 changes: 34 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,40 @@ func TestRequestSetResultAndSetOutputFile(t *testing.T) {
assertEqual(t, `{ "id": "success", "message": "login successful" }`, string(fileContent))
}

func TestRequestFuncs(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()

c := dcnl().
SetQueryParam("client_param", "true").
SetQueryParams(map[string]string{"req_1": "value1", "req_3": "value3"}).
SetDebug(true)

addRequestQueryParams := func(page, size int) func(r *Request) *Request {
return func(r *Request) *Request {
return r.SetQueryParam("page", strconv.Itoa(page)).
SetQueryParam("size", strconv.Itoa(size)).
SetQueryParam("request_no", strconv.Itoa(int(time.Now().Unix())))
}
}

addRequestHeaders := func(r *Request) *Request {
return r.SetHeader(hdrAcceptKey, "application/json").
SetHeader(hdrUserAgentKey, "my-client/v1.0")
}

resp, err := c.R().
Funcs(addRequestQueryParams(1, 100), addRequestHeaders).
SetHeader(hdrUserAgentKey, "Test Custom User agent").
Get(ts.URL + "/")

assertError(t, err)
assertEqual(t, http.StatusOK, resp.StatusCode())
assertEqual(t, "HTTP/1.1", resp.Proto())
assertEqual(t, "200 OK", resp.Status())
assertEqual(t, "TestGet: text response", resp.String())
}

// This test methods exist for test coverage purpose
// to validate the getter and setter
func TestRequestSettingsCoverage(t *testing.T) {
Expand Down