Felipe
Felipe

Reputation: 11887

Can I subclass and redefine a method in Golang?

I'm using a Github Client that allows me to call github API methods more easily.

This library allows me to provide my own *http.Client when I initialize it:

httpClient := &http.Client{}
githubClient := github.NewClient(httpClient)

It works fine but now I need something else. I want to customize the Client so that every request (i.e. the Do method) gets a custom header added.

I've read a bit about embedding and this is what I've tried so far:

package trackerapi

import(
    "net/http"
)

type MyClient struct{
    *http.Client
}

func (my *MyClient)Do(req *http.Request) (*http.Response, error){

    req.Header.Set("cache-control","max-stale=3600")

    return my.Client.Do(req)

}

But the compiler does not let me use my custom MyClient in place of the default one:

httpClient := &trackerapi.MyClient{}

// ERROR: Cannot use httpClient (type *MyClient) as type 
//*http.Client. 
githubClient := github.NewClient(httpClient)

I'm a bit of a golang newbie so my question is: Is this the right way to do what I want to and, if not, what's the recommended approach?

Upvotes: 4

Views: 1288

Answers (1)

Jonathan Hall
Jonathan Hall

Reputation: 79604

Can I subclass ... in Golang?

Short answer: No. Go is not object oriented, therefore it has no classes, therefore subclassing is categorically an impossibility.

Longer answer:

You're on the right track with embedding, but you won't be able to substitute your custom client for anything that expects an *http.Client. This is what Go interfaces are for. But the standard library doesn't use an interface here (it does for some things, where it makes sense).

Another possible approach which may, depending on exact needs, work, is to use a custom transport, rather than a custom client. This does use an interface. You may be able to use a custom RoundTripper that adds the necessary headers, and this you can assign to an *http.Client struct.

Upvotes: 6

Related Questions