Thanks Kevin for these insights. It does seem like the documentation
notes were meant for Go core devs. It would have helped, if the
authors threw in more insight.

I have also been using RoundTripper as client middleware, but so far
largely for authentication. I wanted to expand the scope of the client
middleware in my implementations to do more but looking at the
RoundTripper documentation, I wanted to have views on its use and see
if I can find anti-patterns that I should be aware of.

In fact, since I could not find a lot of useful information around it,
I even felt like writing a blog post highlighting good and bad
patterns using RoundTripper based on the notes I collect.


On Tue, May 12, 2020 at 7:38 AM Kevin Conway <kevinjacobcon...@gmail.com> wrote:
>
> I'll make an attempt to answer this question but I could be wrong given some 
> deeper historical context between the early Go developers.
>
> There are two chunks of the http.RoundTripper comments that folks typically 
> ask about: "should not attempt to handle higher-level protocol details" and 
> "should not modify the request". Unfortunately, the rationale for why these 
> statements are made is neither presented in the comments nor in the patches 
> that introduced them.
>
> It appears "should not modify the request" most likely refers to a 
> concurrency issue that must be mitigated by copying the request before 
> mutating it in the RoundTripper. Here's the change that claims to have 
> resolved an issue surrounding this: https://codereview.appspot.com/5284041. 
> The original comments explicitly allowed for mutating the request but this 
> was changed to "should not" after this patch due to the bug that it resolved.
>
> It's a little harder to find direct evident of the author's intent for 
> "should not attempt to handle higher-level protocol details". This part of 
> the comment has been in the code for nearly a decade and it becomes fairly 
> difficult to track the origin past a set of major renames and large movements 
> of files from place to place within the early Go source code. Reading 
> https://github.com/golang/go/commit/e0a2c5d4b540934e06867710fe7137661a2a39ec 
> makes it seem like these notes were meant for the author or for other Go core 
> devs who were building the original HTTP stack rather than those of us who 
> would use it later. For example, it appears to signal that standard library 
> developers should isolate higher level features within the Client type rather 
> than in the ClientTransport (now RoundTripper) type. I haven't found 
> anything, yet, that suggests the comments are meant for anyone other than 
> developers of the http package in the Go standard library.
>
> From a more practical perspective, you don't really have another choice when 
> it comes to HTTP client middleware that are generally useful in Go 
> applications than the http.RoundTripper interface. If everyone applied the 
> "accept interfaces, return structs" guidelines then you would have more 
> options. For example, if everything that needed an HTTP client accepted a 
> "type Doer { Do(r *http.Request) (*http.Response, Error) }" style interface 
> then you could target your middleware as wrappers for the http.Client. 
> Unfortunately, most projects that allow for injection of a custom HTTP client 
> do so by accepting an instance of *http.Client. Accepting that specific, 
> concrete type makes wrapping anything other than the http.RoundTripper a 
> practical impossibility.
>
> Personally, I've been using http.RoundTripper middleware for several years 
> without issue. It's a solid pattern that can provide an enormous amount of 
> value by allowing re-usable layers of behavior that can be injected into 
> virtually any library or framework that uses an HTTP client. I don't worry 
> about the comments in the standard library for the reasons I listed.
>
> On Mon, May 11, 2020 at 2:01 PM Anuj Agrawal <anujagrawa...@gmail.com> wrote:
>>
>> I am trying to understand in what cases would it make sense to
>> implement my own RoundTripper.
>>
>> If I search about it, I come across examples of RoundTripper that try
>> to do things like caching, retries, authentication, etc. I also read
>> somewhere that there are many RoundTripper implementations that just
>> set the User-Agent header on a request.
>>
>> I know that the documentation says "RoundTrip should not attempt to
>> handle higher-level protocol details such as redirects,
>> authentication, or cookies." And, I also understand that RoundTripper
>> would be a bad place for things like caching.
>>
>> However, I am not able to figure out why is it such a bad idea to use
>> RoundTripper as a middleware that allows me to do some of the higher
>> level things like authentication. After all, authentication is just
>> about interpreting and/or manipulating some headers. In some cases, it
>> could be just as good as setting the User-Agent where all that happens
>> is setting the Authorization header with a token. In some other cases,
>> it could mean interpreting the challenge thrown by the server and then
>> making the same call again with a response to the challenge.
>>
>> Can someone please help me understand this better?
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CABnk5p0k77he6c7Pw0APQJF%2B_FDJFOFdJp_BJ8eS66jbw6%3DG1w%40mail.gmail.com.
>
>
>
> --
> Kevin Conway

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CABnk5p2_c%2BFky3U1LsMPA%2BrA2eCCnox2z538Y99kAV%3DC_3uJAw%40mail.gmail.com.

Reply via email to