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
}