title: Adding custom transport to a third party package
body: <p>I have been using <a href="https://github.com/parnurzeal/gorequest" rel="nofollow noreferrer">GoRequest</a> as a package in my Go application.</p>
  
  <p>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 <code>http.Client</code> is implement outbound rate limiting on the <code>Transport</code>.</p>
  
  <p>For example, in one of my applications I use this - </p>
  
  <pre><code>type rateLimitTransport struct {
      limiter *rate.Limiter
      xport   http.RoundTripper
  }
  
  var _ http.RoundTripper = &amp;rateLimitTransport{}
  
  func newRateLimitTransport(r float64, xport http.RoundTripper) http.RoundTripper {
      return &amp;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),
  }
  </code></pre>
  
  <p>This allows my to create a client, that is rate limited to 1 request per second; 60 requests per minute.</p>
  
  <p>I have forked the GoRequest package and am trying to add a new method to it called <code>SetRateLimit()</code> which should take the rate per second as an argument and use this to implement a rate limited transport.</p>
  
  <p>My attempt so far looks like this:</p>
  
  <pre><code>import (
      //...current imports
      "golang.org/x/time/rate"
  )
  //... Rest of the package
  type rateLimitTransport struct {
      limiter *rate.Limiter
      xport   http.RoundTripper
  }
  
  var _ http.RoundTripper = &amp;rateLimitTransport{}
  
  func newRateLimitTransport(r float64, xport http.RoundTripper) http.RoundTripper {
      return &amp;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
  }
  </code></pre>
  
  <p>However I get an error when trying to build this:</p>
  
  <blockquote>
    <p>cannot use newRateLimitTransport(limit, http.DefaultTransport) (type http.RoundTripper) as type *http.Transport in assignment: need type assertion</p>
  </blockquote>
  
  <p>I've been looking at this for hours, and I don't quite understand how this works for a regular <code>http.Client</code> but doesn't work for this package.</p>
  
  <p><strong>Can someone please help me resolve the issue above and add rate limiting to this package?</strong></p>
  
  <p><strong>Update - SuperRequest struct</strong></p>
  
  <pre><code>// 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
  }
  </code></pre>