Skip to content
GoRequest -- Simplified HTTP client ( inspired by nodejs SuperAgent )
Branch: develop
Clone or download
Pull request Compare This branch is 1 commit ahead, 105 commits behind parnurzeal:develop.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


GoRequest -- Simplified HTTP client ( inspired by famous SuperAgent lib in Node.js )


"Shooting Requests like a Machine Gun" - Gopher

Sending request would never been fun and easier than this. It comes with lots of feature:

  • Get/Post/Put/Head/Delete/Patch/Options
  • Set - simple header setting
  • JSON - made it simple with JSON string as a parameter
  • Proxy - sending request via proxy
  • Timeout - setting timeout for a request
  • TLSClientConfig - taking control over tls where at least you can disable security check for https
  • RedirectPolicy
  • Cookie - setting cookies for your request
  • CookieJar - automatic in-memory cookiejar
  • BasicAuth - setting basic authentication header
  • more to come..


$ go get


See Go Doc or Go Walker for usage and details.


Drone Build Status Travis Build Status

Why should you use GoRequest?

GoRequest makes thing much more simple for you, making http client more awesome and fun like SuperAgent + golang style usage.

This is what you normally do for a simple GET without GoRequest:

resp, err := http.Get("")

With GoRequest:

request := gorequest.New()
resp, body, errs := request.Get("").End()

Or below if you don't want to reuse it for other requests.

resp, body, errs := gorequest.New().Get("").End()

How about getting control over HTTP client headers, redirect policy, and etc. Things is getting more complicated in golang. You need to create a Client, setting header in different command, ... to do just only one GET

client := &http.Client{
  CheckRedirect: redirectPolicyFunc,

req, err := http.NewRequest("GET", "", nil)

req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)

Why making things ugly while you can just do as follows:

request := gorequest.New()
resp, body, errs := request.Get("").
  Set("If-None-Match", `W/"wyzzy"`).

DELETE, HEAD, POST, PUT, PATCH are now supported and can be used the same way as GET:

request := gorequest.New()
resp, body, errs := request.Post("").End()
// PUT -> request.Put("").End()
// DELETE -> request.Delete("").End()
// HEAD -> request.Head("").End()
// ANYTHING -> request.CustomMethod("TRACE", "").End()


For a JSON POST with standard libraries, you might need to marshal map data structure to json format, setting header to 'application/json' (and other headers if you need to) and declare http.Client. So, you code become longer and hard to maintain:

m := map[string]interface{}{
  "name": "backy",
  "species": "dog",
mJson, _ := json.Marshal(m)
contentReader := bytes.NewReader(mJson)
req, _ := http.NewRequest("POST", "", contentReader)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Notes","GoRequest is coming!")
client := &http.Client{}
resp, _ := client.Do(req)

Compared to our GoRequest version, JSON is for sure a default. So, it turns out to be just one simple line!:

request := gorequest.New()
resp, body, errs := request.Post("").
  Set("Notes","gorequst is coming!").
  Send(`{"name":"backy", "species":"dog"}`).

Moreover, it also supports struct type. So, you can have a fun Mix & Match sending the different data types for your request:

type BrowserVersionSupport struct {
  Chrome string
  Firefox string
ver := BrowserVersionSupport{ Chrome: "37.0.2041.6", Firefox: "30.0" }
request := gorequest.New()
resp, body, errs := request.Post("").

Not only for Send() but Query() is also supported. Just give it a try! :)


Moreover, GoRequest also supports callback function. This gives you much more flexibility on using it. You can use it any way to match your own style! Let's see a bit of callback example:

func printStatus(resp gorequest.Response, body string, errs []error){


In the case when you are behind proxy, GoRequest can handle it easily with Proxy func:

request := gorequest.New().Proxy("http://proxy:999")
resp, body, errs := request.Get("").End()
// To reuse same client with no_proxy, use empty string:
resp, body, errs = request.Proxy("").Get("").End()

Basic Authentication

To add a basic authentication header:

request := gorequest.New().SetBasicAuth("username", "password")
resp, body, errs := request.Get("").End()


Timeout can be set in any time duration using time package:

request := gorequest.New().Timeout(2*time.Millisecond)
resp, body, errs:= request.Get("").End()

Timeout func defines both dial + read/write timeout to the specified time parameter.


Thanks to @jaytaylor, we now have EndBytes to use when you want the body as bytes.

The callbacks work the same way as with End, except that a byte array is used instead of a string.

resp, bodyBytes, errs := gorequest.New().Get("").EndBytes()


For debugging, GoRequest leverages httputil to dump details of every request/response. (Thanks to @dafang)

You can just use SetDebug to enable/disable debug mode and SetLogger to set your own choice of logger.

Thanks to @QuentinPerez, we can see even how gorequest is compared to CURL by using SetCurlCommand.


As the underlying gorequest is based on http.Client in most use cases, gorequest.New() should be called once and reuse gorequest as much as possible.

Contributing to GoRequest:

If you find any improvement or issue you want to fix, feel free to send me a pull request with testing.

Thanks to all contributors thus far:

@kemadz, @austinov, @figlief, @dickeyxxx, @killix, @jaytaylor, @na-ga, @dafang, @alaingilbert, @6david9, @pencil001, @QuentinPerez, @smallnest, @piotrmiskiewicz, @coderhaoxin, and @WaveCutz

Also, co-maintainer is needed here. If anyone is interested, please email me (parnurzeal at


  • Renee French - the creator of Gopher mascot
  • Wisi Mongkhonsrisawat for providing an awesome GoRequest's Gopher image :)


GoRequest is MIT License.

You can’t perform that action at this time.