Adding custom transport to a third party package

I have been using GoRequest as a package in my Go application.

I use it as it helps make all the API calls I need to make a lot cleaner - one thing that it is lacking, that I am able to do with a regular http.Client is implement outbound rate limiting on the Transport.

For example, in one of my applications I use this -

type rateLimitTransport struct {
    limiter *rate.Limiter
    xport   http.RoundTripper
}

var _ http.RoundTripper = &rateLimitTransport{}

func newRateLimitTransport(r float64, xport http.RoundTripper) http.RoundTripper {
    return &rateLimitTransport{
        limiter: rate.NewLimiter(rate.Limit(r), 1),
        xport:   xport,
    }
}

func (t *rateLimitTransport) RoundTrip(r *http.Request) (*http.Response, error) {
    t.limiter.Wait(r.Context())
    return t.xport.RoundTrip(r)
}

var myClient = http.Client{
    // Use a rate-limiting transport which falls back to the default
    Transport: newRateLimitTransport(1, http.DefaultTransport),
}

This allows my to create a client, that is rate limited to 1 request per second; 60 requests per minute.

I have forked the GoRequest package and am trying to add a new method to it called SetRateLimit() which should take the rate per second as an argument and use this to implement a rate limited transport.

My attempt so far looks like this:

import (
    //...current imports
    "golang.org/x/time/rate"
)
//... Rest of the package
type rateLimitTransport struct {
    limiter *rate.Limiter
    xport   http.RoundTripper
}

var _ http.RoundTripper = &rateLimitTransport{}

func newRateLimitTransport(r float64, xport http.RoundTripper) http.RoundTripper {
    return &rateLimitTransport{
        limiter: rate.NewLimiter(rate.Limit(r), 1),
        xport:   xport,
    }
}

func (t *rateLimitTransport) RoundTrip(r *http.Request) (*http.Response, error) {
    t.limiter.Wait(r.Context())
    return t.xport.RoundTrip(r)
}

func (s *SuperAgent) SetRateLimit(limit float64) *SuperAgent {

    s.Transport = newRateLimitTransport(limit, http.DefaultTransport)
    return s
}

However I get an error when trying to build this:

cannot use newRateLimitTransport(limit, http.DefaultTransport) (type http.RoundTripper) as type *http.Transport in assignment: need type assertion

I've been looking at this for hours, and I don't quite understand how this works for a regular http.Client but doesn't work for this package.

Can someone please help me resolve the issue above and add rate limiting to this package?

Update - SuperRequest struct

// A SuperAgent is a object storing all request data for client.
type SuperAgent struct {
    Url               string
    Method            string
    Header            http.Header
    TargetType        string
    ForceType         string
    Data              map[string]interface{}
    SliceData         []interface{}
    FormData          url.Values
    QueryData         url.Values
    FileData          []File
    BounceToRawString bool
    RawString         string
    Client            *http.Client
    Transport         *http.Transport
    Cookies           []*http.Cookie
    Errors            []error
    BasicAuth         struct{ Username, Password string }
    Debug             bool
    CurlCommand       bool
    logger            Logger
    Retryable         struct {
        RetryableStatus []int
        RetryerTime     time.Duration
        RetryerCount    int
        Attempt         int
        Enable          bool
    }
    //If true prevents clearing Superagent data and makes it possible to reuse it for the next requests
    DoNotClearSuperAgent bool
}

1 answer

  • answered 2018-02-13 02:40 Anuruddha

    Error you are seeing says the issue.

    cannot use newRateLimitTransport(limit, http.DefaultTransport) (type http.RoundTripper) as type *http.Transport in assignment: need type assertion

    SuperAgent.Transport type is *http.Transport But you are trying to assign http.RoundTripper to that field

    To fix this you could change the SuperaAgent

    type SuperAgent{
    ...
    Transport  http.RoundTripper
    ...
    }