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

add get/set context data in request #358

Closed
wants to merge 1 commit into from

Conversation

RonaldinhoL
Copy link
Contributor

add method for keep data during different callback and different retry round

@imroc
Copy link
Owner

imroc commented May 28, 2024

You can use the go std context.Context to store your key/value pair context data, there is no need to add other functions and fields.

For example:

package main

import (
	"context"
	"fmt"

	"github.com/imroc/req/v3"
)

func printContextValue(hookName string, req *req.Request) {
	val, ok := req.Context().Value("test1").(string)
	if !ok {
		panic("no value found")
	}
	fmt.Println(hookName, "found test1: ", val)
}

func main() {
	client := req.C().
		SetCommonRetryCount(3).
		SetCommonRetryHook(func(resp *req.Response, err error) {
			req := resp.Request
			printContextValue("retry hook", req)
		}).
		SetCommonRetryCondition(func(resp *req.Response, err error) bool {
			return true
		}).
		OnBeforeRequest(func(client *req.Client, req *req.Request) error {
			printContextValue("request middleware", req)
			return nil
		})

	ctx := context.Background()
	ctx = context.WithValue(ctx, "test1", "data1")
	client.R().SetContext(ctx).MustGet("https://httpbin.org/get")
}

@RonaldinhoL
Copy link
Contributor Author

this is not really convenient tho, i have common retry hooks but i need to add ctx value explicitly for every requests, which may only be used during retry and has nothing to do with current request

@imroc
Copy link
Owner

imroc commented May 28, 2024

You're right, I can add this to Request (use context.Context to store data, no extra field):

func (r *Request) SetContextData(key, val any) *Request {
	r.ctx = context.WithValue(r.Context(), key, val)
	return r
}

func (r *Request) GetContextData(key any) any {
	return r.Context().Value(key)
}

Then it will be more convenient.

imroc added a commit that referenced this pull request May 28, 2024
@RonaldinhoL
Copy link
Contributor Author

could it be modified in this way ? SetContextData same key and diffrent value

@imroc
Copy link
Owner

imroc commented May 28, 2024

could it be modified in this way ? SetContextData same key and diffrent value

Yes,new value will override the old value.

e.g.

package main

import (
	"fmt"

	"github.com/imroc/req/v3"
)

func main() {
	client := req.C().
		SetCommonRetryCount(3).
		SetCommonRetryHook(func(resp *req.Response, err error) {
			req := resp.Request
			if req.RetryAttempt > 0 { // set data on retry
				req.SetContextData("test1", fmt.Sprintf("data-%d", req.RetryAttempt))
			}
		}).
		SetCommonRetryCondition(func(resp *req.Response, err error) bool {
			return true
		}).
		OnBeforeRequest(func(client *req.Client, req *req.Request) error {
			fmt.Println("get data in middleware", req.GetContextData("test1"))
			return nil
		})

	client.R().MustGet("https://httpbin.org/get")
}

Output:

get data in middleware <nil>
get data in middleware data-1
get data in middleware data-2
get data in middleware data-3

@imroc
Copy link
Owner

imroc commented May 28, 2024

Now you can upgrade to the latest release.

@RonaldinhoL
Copy link
Contributor Author

cool great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants