top
(README.md)
[![Build Status](https://img.shields.io/travis/franela/goreq/master.svg)](https://travis-ci.org/franela/goreq)
[![GoDoc](https://godoc.org/github.com/franela/goreq?status.svg)](https://godoc.org/github.com/franela/goreq)

GoReq
=======

Simple and sane HTTP request library for Go language.



**Table of Contents**

- [Why GoReq?](#user-content-why-goreq)
- [How do I install it?](#user-content-how-do-i-install-it)
- [What can I do with it?](#user-content-what-can-i-do-with-it)
  - [Making requests with different methods](#user-content-making-requests-with-different-methods)
  - [GET](#user-content-get)
    - [Tags](#user-content-tags)
  - [POST](#user-content-post)
    - [Sending payloads in the Body](#user-content-sending-payloads-in-the-body)
  - [Specifiying request headers](#user-content-specifiying-request-headers)
  - [Sending Cookies](#cookie-support)
  - [Setting timeouts](#user-content-setting-timeouts)
 - [Using the Response and Error](#user-content-using-the-response-and-error)
 - [Receiving JSON](#user-content-receiving-json)
 - [Sending/Receiving Compressed Payloads](#user-content-sendingreceiving-compressed-payloads)
    - [Using gzip compression:](#user-content-using-gzip-compression)
    - [Using deflate compression:](#user-content-using-deflate-compression)
    - [Using compressed responses:](#user-content-using-compressed-responses)
 - [Proxy](#proxy)
 - [Debugging requests](#debug)
     - [Getting raw Request & Response](#getting-raw-request--response)
 - [TODO:](#user-content-todo)



Why GoReq?
==========

Go has very nice native libraries that allows you to do lots of cool things. But sometimes those libraries are too low level, which means that to do a simple thing, like an HTTP Request, it takes some time. And if you want to do something as simple as adding a timeout to a request, you will end up writing several lines of code.

This is why we think GoReq is useful. Because you can do all your HTTP requests in a very simple and comprehensive way, while enabling you to do more advanced stuff by giving you access to the native API.

How do I install it?
====================

```bash
go get github.com/franela/goreq
```

What can I do with it?
======================

## Making requests with different methods

#### GET
```go
res, err := goreq.Request{ Uri: "http://www.google.com" }.Do()
```

GoReq default method is GET.

You can also set value to GET method easily

```go
type Item struct {
        Limit int
        Skip int
        Fields string
}

item := Item {
        Limit: 3,
        Skip: 5,
        Fields: "Value",
}

res, err := goreq.Request{
        Uri: "http://localhost:3000/",
        QueryString: item,
}.Do()
```
The sample above will send `http://localhost:3000/?limit=3&skip=5&fields=Value`

Alternatively the `url` tag can be used in struct fields to customize encoding properties

```go
type Item struct {
        TheLimit int `url:"the_limit"`
        TheSkip string `url:"the_skip,omitempty"`
        TheFields string `url:"-"`
}

item := Item {
        TheLimit: 3,
        TheSkip: "",
        TheFields: "Value",
}

res, err := goreq.Request{
        Uri: "http://localhost:3000/",
        QueryString: item,
}.Do()
```
The sample above will send `http://localhost:3000/?the_limit=3`


QueryString also support url.Values

```go
item := url.Values{}
item.Set("Limit", 3)
item.Add("Field", "somefield")
item.Add("Field", "someotherfield")

res, err := goreq.Request{
        Uri: "http://localhost:3000/",
        QueryString: item,
}.Do()
```

The sample above will send `http://localhost:3000/?limit=3&field=somefield&field=someotherfield`

### Tags

Struct field `url` tag is mainly used as the request parameter name.
Tags can be comma separated multiple values, 1st value is for naming and rest has special meanings.

- special tag for 1st value
    - `-`: value is ignored if set this

- special tag for rest 2nd value
    - `omitempty`: zero-value is ignored if set this
    - `squash`: the fields of embedded struct is used for parameter

#### Tag Examples

```go
type Place struct {
    Country string `url:"country"`
    City    string `url:"city"`
    ZipCode string `url:"zipcode,omitempty"`
}

type Person struct {
    Place `url:",squash"`

    FirstName string `url:"first_name"`
    LastName  string `url:"last_name"`
    Age       string `url:"age,omitempty"`
    Password  string `url:"-"`
}

johnbull := Person{
	Place: Place{ // squash the embedded struct value
		Country: "UK",
		City:    "London",
		ZipCode: "SW1",
	},
	FirstName: "John",
	LastName:  "Doe",
	Age:       "35",
	Password:  "my-secret", // ignored for parameter
}

goreq.Request{
	Uri:         "http://localhost/",
	QueryString: johnbull,
}.Do()
// =>  `http://localhost/?first_name=John&last_name=Doe&age=35&country=UK&city=London&zip_code=SW1`


// age and zipcode will be ignored because of `omitempty`
// but firstname isn't.
samurai := Person{
	Place: Place{ // squash the embedded struct value
		Country: "Japan",
		City:    "Tokyo",
	},
	LastName: "Yagyu",
}

goreq.Request{
	Uri:         "http://localhost/",
	QueryString: samurai,
}.Do()
// =>  `http://localhost/?first_name=&last_name=yagyu&country=Japan&city=Tokyo`
```


#### POST

```go
res, err := goreq.Request{ Method: "POST", Uri: "http://www.google.com" }.Do()
```

## Sending payloads in the Body

You can send ```string```, ```Reader``` or ```interface{}``` in the body. The first two will be sent as text. The last one will be marshalled to JSON, if possible.

```go
type Item struct {
    Id int
    Name string
}

item := Item{ Id: 1111, Name: "foobar" }

res, err := goreq.Request{
    Method: "POST",
    Uri: "http://www.google.com",
    Body: item,
}.Do()
```

## Specifiying request headers

We think that most of the times the request headers that you use are: ```Host```, ```Content-Type```, ```Accept``` and ```User-Agent```. This is why we decided to make it very easy to set these headers.

```go
res, err := goreq.Request{
    Uri: "http://www.google.com",
    Host: "foobar.com",
    Accept: "application/json",
    ContentType: "application/json",
    UserAgent: "goreq",
}.Do()
```

But sometimes you need to set other headers. You can still do it.

```go
req := goreq.Request{ Uri: "http://www.google.com" }

req.AddHeader("X-Custom", "somevalue")

req.Do()
```

Alternatively you can use the `WithHeader` function to keep the syntax short

```go
res, err = goreq.Request{ Uri: "http://www.google.com" }.WithHeader("X-Custom", "somevalue").Do()
```

## Cookie support

Cookies can be either set at the request level by sending a [CookieJar](http://golang.org/pkg/net/http/cookiejar/) in the `CookieJar` request field
or you can use goreq's one-liner WithCookie method as shown below

```go
res, err := goreq.Request{
    Uri: "http://www.google.com",
}.
WithCookie(&http.Cookie{Name: "c1", Value: "v1"}).
Do()
```

## Setting timeouts

GoReq supports 2 kind of timeouts. A general connection timeout and a request specific one. By default the connection timeout is of 1 second. There is no default for request timeout, which means it will wait forever.

You can change the connection timeout doing:

```go
goreq.SetConnectTimeout(100 * time.Millisecond)
```

And specify the request timeout doing:

```go
res, err := goreq.Request{
    Uri: "http://www.google.com",
    Timeout: 500 * time.Millisecond,
}.Do()
```

## Using the Response and Error

GoReq will always return 2 values: a ```Response``` and an ```Error```.
If ```Error``` is not ```nil``` it means that an error happened while doing the request and you shouldn't use the ```Response``` in any way.
You can check what happened by getting the error message:

```go
fmt.Println(err.Error())
```
And to make it easy to know if it was a timeout error, you can ask the error or return it:

```go
if serr, ok := err.(*goreq.Error); ok {
    if serr.Timeout() {
        ...
    }
}
return err
```

If you don't get an error, you can safely use the ```Response```.

```go
res.Uri // return final URL location of the response (fulfilled after redirect was made)
res.StatusCode // return the status code of the response
res.Body // gives you access to the body
res.Body.ToString() // will return the body as a string
res.Header.Get("Content-Type") // gives you access to all the response headers
```
Remember that you should **always** close `res.Body` if it's not `nil`

## Receiving JSON

GoReq will help you to receive and unmarshal JSON.

```go
type Item struct {
    Id int
    Name string
}

var item Item

res.Body.FromJsonTo(&item)
```

## Sending/Receiving Compressed Payloads
GoReq supports gzip, deflate and zlib compression of requests' body and transparent decompression of responses provided they have a correct `Content-Encoding` header.

#####Using gzip compression:
```go
res, err := goreq.Request{
    Method: "POST",
    Uri: "http://www.google.com",
    Body: item,
    Compression: goreq.Gzip(),
}.Do()
```
#####Using deflate/zlib compression:
```go
res, err := goreq.Request{
    Method: "POST",
    Uri: "http://www.google.com",
    Body: item,
    Compression: goreq.Deflate(),
}.Do()
```
#####Using compressed responses:
If servers replies a correct and matching `Content-Encoding` header (gzip requires `Content-Encoding: gzip` and deflate `Content-Encoding: deflate`) goreq transparently decompresses the response so the previous example should always work:
```go
type Item struct {
    Id int
    Name string
}
res, err := goreq.Request{
    Method: "POST",
    Uri: "http://www.google.com",
    Body: item,
    Compression: goreq.Gzip(),
}.Do()
var item Item
res.Body.FromJsonTo(&item)
```
If no `Content-Encoding` header is replied by the server GoReq will return the crude response.

## Proxy
If you need to use a proxy for your requests GoReq supports the standard `http_proxy` env variable as well as manually setting the proxy for each request

```go
res, err := goreq.Request{
    Method: "GET",
    Proxy: "http://myproxy:myproxyport",
    Uri: "http://www.google.com",
}.Do()
```

### Proxy basic auth is also supported

```go
res, err := goreq.Request{
    Method: "GET",
    Proxy: "http://user:pass@myproxy:myproxyport",
    Uri: "http://www.google.com",
}.Do()
```

## Debug
If you need to debug your http requests, it can print the http request detail.

```go
res, err := goreq.Request{
	Method:      "GET",
	Uri:         "http://www.google.com",
	Compression: goreq.Gzip(),
	ShowDebug:   true,
}.Do()
fmt.Println(res, err)
```

and it will print the log:
```
GET / HTTP/1.1
Host: www.google.com
Accept:
Accept-Encoding: gzip
Content-Encoding: gzip
Content-Type:
```


### Getting raw Request & Response 

To get the Request:

```go
req := goreq.Request{
        Host: "foobar.com",
}

//req.Request will return a new instance of an http.Request so you can safely use it for something else
request, _ := req.NewRequest()

```


To get the Response:

```go
res, err := goreq.Request{
	Method:      "GET",
	Uri:         "http://www.google.com",
	Compression: goreq.Gzip(),
	ShowDebug:   true,
}.Do()

// res.Response will contain the original http.Response structure 
fmt.Println(res.Response, err)
```




TODO:
-----

We do have a couple of [issues](https://github.com/franela/goreq/issues) pending we'll be addressing soon. But feel free to
contribute and send us PRs (with tests please :smile:).

Imported by 103 package(s)

  1. git.ishopex.cn/xushuai/wechat
  2. github.com/1995parham/gosimac/bing
  3. github.com/Attamusc/be-janky/lib
  4. github.com/Attamusc/go-behance
  5. github.com/ChannelMeter/vault-gatekeeper-mesos
  6. github.com/ChristopherRabotin/sg
  7. github.com/DylanFM/incident-worker
  8. github.com/Financial-Times/next-flags-cli
  9. github.com/Gr1N/pacman/modules/oauth2
  10. github.com/Jasrags/movie-chains/tmdb
  11. github.com/Jasrags/movie-chains/untappd
  12. github.com/JohnSmithX/wechat_component
  13. github.com/LeandroGuillen/gongsi
  14. github.com/MarvinMenzerath/UpAndRunning2
  15. github.com/MarvinMenzerath/UpAndRunning2/lib
  16. github.com/TykTechnologies/tykcommon
  17. github.com/Xorlev/fargo
  18. github.com/aaronv01/lol-bets/swagger
  19. github.com/anansii/github-updater
  20. github.com/anansii/solutionist
  21. github.com/attamusc/be-janky/lib
  22. github.com/attamusc/go-behance
  23. github.com/bfontaine/Antroid/api
  24. github.com/bfontaine/antroid/api
  25. github.com/boivie/lovebeat
  26. github.com/boivie/lovebeat-go
  27. github.com/boivie/lovebeat-go/alert
  28. github.com/boivie/lovebeat-go/notify
  29. github.com/boivie/lovebeat/alert
  30. github.com/boivie/lovebeat/notify
  31. github.com/boivie/undergang/app
  32. github.com/bpicolo/picfit/http
  33. github.com/cabify/cbot/commands
  34. github.com/castaneai/kirara/resource
  35. github.com/citruspi/Ludicrous-MV-Client
  36. github.com/clonkspot/stream-notification
  37. github.com/cloudimmunity/docker-slim/master/inspectors/container/probes/http
  38. github.com/codeskyblue/boxtool
  39. github.com/cowai/go-redundanthls
  40. github.com/cquinn/fargo
  41. github.com/crunchyroll/picfit/storage
  42. github.com/davidraba/go-iot/util/gongsi
  43. github.com/deepglint/nsqelastic
  44. github.com/divshot/gitling/server
  45. github.com/ellcrys/openmint/lib
  46. github.com/espebra/tyk
  47. github.com/evalphobia/goreq-wrapper/request
  48. github.com/fourcube/goiban-service/metrics
  49. github.com/franela/go-supertest
  50. github.com/giefferre/codemotion_soapclient
  51. github.com/globocom/galf
  52. github.com/hartfordfive/brigade/node
  53. github.com/hartfordfive/gots
  54. github.com/hudl/fargo
  55. github.com/igrybkov/leosync/src/lingualeo/api
  56. github.com/istrategylabs/heroku-cli
  57. github.com/istrategylabs/heroku-cli/gode
  58. github.com/jfbus/picfit/http
  59. github.com/jianfeiliao/fargo
  60. github.com/jinpark/learngo
  61. github.com/joyplus/adexchange/engine
  62. github.com/joyplus/fenqiwanh5/invokers
  63. github.com/jpoehls/go-tableaupublic
  64. github.com/jqs7/Jqs7Bot/helper
  65. github.com/jqs7/Jqs7Bot/plugin
  66. github.com/judsonco/proxycrush
  67. github.com/leandroguillen/gongsi
  68. github.com/lonelycode/tykcommon
  69. github.com/magnusbaeck/lovebeat/alert
  70. github.com/mcmadhatter/sphere-lwrf
  71. github.com/miller-hacks/cligma
  72. github.com/mindcastio/mindcastio/backend/util
  73. github.com/mithereal/go-ebay
  74. github.com/mithereal/go-ebay/examples/getmessages
  75. github.com/mnhkahn/cyeam_post/dao
  76. github.com/nsf/picfit/http
  77. github.com/opsgenie/opsgenie-go-sdk/client
  78. github.com/patrickdappollonio/twitch-stream/twitch
  79. github.com/patrickdappollonio/wikipedia-state-county
  80. github.com/pavel-kazhavets/web_exporter
  81. github.com/pivotal-pez/pezdispenser/innkeeperclient
  82. github.com/rexposadas/simulate
  83. github.com/rexposadas/simulate/examples/fakeapi
  84. github.com/rexposadas/simulate/examples/simpleget
  85. github.com/rollbackup/asgard-cli
  86. github.com/ruqqq/nuswherebot
  87. github.com/sciffer/opsgenie-go-sdk/client
  88. github.com/skygeario/skygear-server/pkg/server/asset
  89. github.com/st3v/fargo
  90. github.com/svenkreiss/dockbroker/api
  91. github.com/themartorana/Gostmark/internal
  92. github.com/thoas/picfit/storage
  93. github.com/tietang/fargo
  94. github.com/tomsteele/burpstaticscan
  95. github.com/tooltwist/useme-statuswall
  96. github.com/topdeskde/solutionist
  97. github.com/victortrac/opsgenie-go-sdk/client
  98. github.com/wangtuanjie/picfit/http
  99. github.com/wicast/moe-words-library/src/crawler
  100. github.com/xmvper/exchange-go/client
  101. github.com/xorlev/fargo
  102. github.com/yukirin/goyuki/command
  103. gitlab.com/wmlph/poloniex-api

Test imports 2 package(s)

  1. github.com/onsi/gomega
  2. github.com/franela/goblin