-[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.
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
typeItemstruct{
Idint
Namestring
}
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
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
ifserr,ok:=err.(*goreq.Error);ok{
ifserr.Timeout(){
...
}
}
returnerr
```
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
typeItemstruct{
Idint
Namestring
}
varitemItem
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
typeItemstruct{
Idint
Namestring
}
res,err:=goreq.Request{
Method:"POST",
Uri:"http://www.google.com",
Body:item,
Compression:goreq.Gzip(),
}.Do()
varitemItem
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:).