h2non/gentleman

Allow client setting methods reusability

solher opened this issue · 5 comments

I may be wrong but for now, it seems that the setting client methods such as func (c *Client) BaseURL(uri string) *Client only allows one time uses.

You can't really do:

cli := gentleman.New()
cli.BaseURL("foo.com")
cli.BaseURL("bar.com")

Because a new middleware is added each time.

The thing is I really need that kind of feature to use gentleman in a database driver because I need to be able to switch the DB url at any time, without touching the other middlewares.

I'm pretty sure there must be a workaround to do that right now. What would be the best way ?

h2non commented

You can rely on the Request instance to do that, which is specifically designed for that kind of purposes.

There're basically two high level entities: Client -> Request.

  • Client can inherit from other Client.
  • Request can inherit from Client.
  • Client is designed for reusability.
  • Client can create multiple Request who implicitly inherits from the current Client.
  • Both Client and Request are full middleware capable.

In other words, you can do the following using both entities:

// Create base reusable client
cli := gentleman.New()
// By default we use foo.com
cli.BaseURL("foo.com")

// Then override the URL for specific scenarios, for instance on every call to DB.
req := cli.Request()
req.BaseURL("bar.com") 

// When you're done, perform the request
res, err := req.Send()

Another approach could be creating a parent Client, and then create child Client entities who inherits from parent.

I've to explain that kind of things better in the docs.

I could use the request instance for sure but one of the feature I like in gentleman is the ability to set common things in the client.
And a DB url is something almost static. It can change once in a while but thousands of queries can be done in between to the same url.
That's why I'd like to keep the url/auth headers in the client and only keep the body/method in the request. The things which are really dynamic.

I'm going to try to find something using inheritance.

h2non commented

You can write your own plugin/middleware which exposes the API you need to perform that kind of changes.

Works like a charm, thank you !

h2non commented

Cool. Then I'm closing the issue.