Skip to content

Proposal: Add Context() method into Request and consider logging prerequesthook updates #206

@clippit

Description

@clippit

Hi,

Firstly thank you for creating such a great tool! 😄

I find it's inconvenient for passing user custom parameters when using user-defined middleware. For example, in our development process, the server may receive an X-Request-ID header and it should pass this header to any services it calls. That's a simple way for tracing RPC calling actually. Besides of this, we also have some requirements for generating signature per request.

For current version of resty, the only way to approach this is using SetPreRequestHook and carrying user values with req.RawRequest.Context(), e.g:

client.SetPreRequestHook(func(c *resty.Client, req *resty.Request) error {
	requestId, ok := req.RawRequest.Context().Value(requestIdKey).(string)
	if ok && requestId != "" {
		req.SetHeader("x-request-id", requestId)
	}

	authKey, ok := req.RawRequest.Context().Value(authKey).(string)
	if !ok {
		return errors.New("no auth key in request context")
	}

	// ... grab request info to generate signature...
	req.SetHeader("x-signature", "...")

	return nil
})

When using this client, we need a nested context to store these values:

ctx := context.WithValue(context.Background(), requestIdKey, "from_current_server_request_header")
ctx = context.WithValue(ctx, authKey, "may_returned_by_another_service")
client.R().SetContext(ctx).Get("/")

We can only use SetPreRequestHook rather than OnBeforeRequest because RawRequest is created after all OnBeforeRequest middlewares and the context of RawRequest if the only place that can carry these values. But there are some shortcoming:

  1. The headers added in SetPreRequestHook cannot be printed when debug is on since requestLogger happens before this hook
  2. It's not so good to create so many context

So here is my modest proposal. A GetContext() method can be added into Request so we can put these codes in OnBeforeRequest and make request logger prints completed headers. Furthermore, the Request may contain a map[string]interface{} registry to store any kind of user values to get more abilities.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions