rek
An easy HTTP client for Go, inspired by Requests. Here's an example:
type Comment struct {
Body string `json:"body"`
}
comment := Comment{Body: "This movie sucked"}
headers := map[string]string{"My-Custom-Header", "foo,bar,baz"}
res, err := rek.Post("https://httpbin.org/post",
rek.Json(comment),
rek.Headers(headers),
rek.BasicAuth("user", "pass"),
rek.Timeout(5 * time.Second),
)
fmt.Println(res.StatusCode())
fmt.Println(res.Text())
Responses
The Response
struct has the following methods:
Method | Description | Return type |
---|---|---|
StatusCode() |
HTTP status code, e.g. 200, 400 | int |
Content() |
The raw response body content | []byte |
Headers() |
The response headers | map[string]string |
Encoding() |
The content encoding of the response body, e.g. gzip |
[]string |
Text() |
The response body as a string | string |
ContentType() |
The value of the Content-Type header |
string |
Json(interface{}) |
Marshals the response body into JSON | error |
Raw() |
The unmodified *http.Response |
*http.Response |
Cookies() |
The cookies attached to the response | []*http.Cookie |
ContentLength() |
The length of the response | int64 |
Status() |
The status of the response, e.g. 200 OK |
string |
Options
Headers
headers := map[string]string{
"My-Custom-Header": "foo,bar,baz",
}
res, err := rek.Post("https://httpbin.org/post", rek.Headers(headers))
JSON
Pass in any struct:
type Comment struct {
ID int64 `json:"id"`
Body string `json:"body"`
Timestamp time.Time `json:"timestamp"`
}
comment := Comment{ID:47, Body:"Cool movie!", Timestamp: time.Now()}
res, err := rek.Post("https://httpbin.org/post", rek.Json(comment))
Request headers are automatically updated to include
Content-Type
asapplication/json;charset=utf-8
.
Request timeout
res, err := rek.Get("https://httpbin.org/get", rek.Timeout(5 * time.Second))
Form data
form := map[string]string{
"foo": "bar",
"baq": "baz",
}
res, err := rek.Put("https://httpbin.org/put", rek.FormData(form))
File upload
fieldName := "file"
filepath := "docs/README.md"
params := nil
res, err := rek.Post("https:/httpbin.org/post", rek.File(fieldName, filepath, params))
Request headers are automatically updated to include
Content-Type
asmultipart/form-data; boundary=...
.
Basic auth
username, password := "user", "pass"
res, _ := rek.Get(fmt.Sprintf("https://httpbin.org/basic-auth/%s/%s", username, password),
rek.BasicAuth(username, password))
fmt.Println(res.StatusCode()) // 200
res, _ := rek.Get(fmt.Sprintf("https://httpbin.org/basic-auth/%s/other", username, password),
rek.BasicAuth(username, password))
fmt.Println(res.StatusCode()) // 401
Data
Takes any input and serializes it to a []byte
:
data := map[string]interface{
"age": 38,
"name": "Luc",
}
res, err := rek.Post("https://httpbin.org/post", rek.Data(data))
Request headers are automatically updated to include
Content-Type
asapplication/octet-stream
.
User agent
res, err := rek.Post("https://httpbin.org/post", rek.UserAgent("ThisGuy"))
Bearer (useful for JSON Web Tokens)
token := "... token ..."
res, err := rek.Post("https://httpbin.org/post", rek.Bearer(token))
Request modifier
Supply a function that modifies the *http.Request
(after all other supplied options have been applied to the request):
modifier := func(r *http.Request) {
// Do whatever you want with the request
}
res, err := rek.Get("https://httpbin.org/get", rek.RequestModifier(modifier))
Accept
Apply an Accept
header to the request:
res, err := rek.Get("https://httpbin.org/get", rek.Accept("application/tar+gzip"))
API key
Add an API key to the request as an Authorization
header (where the value is Basic ${KEY}
):
res, err := rek.Get("https://some-secure-api.io", rek.ApiKey("a1b2c3..."))
Context
Supply a Context
to the request:
ctx, cancel := context.WithCancel(context.Background())
res, err := rek.Get("https://long-winded-api.io", rek.Context(ctx))
// Ugh, I don't want this request to happen anymore
cancel()
Validation
It's important to bear in mind that rek provides no validation for the options that you provide on a specific request and doesn't provide any constraints on which options can be used with which request method. Some options may not make sense for some methods, e.g. request JSON on a HEAD
request, but I leave it up to the end user to supply their own constraints. One exception is that the request body can only be set once. If you attempt to set it more than once you'll get a ErrRequestBodySetMultipleTimes
error. This, for example, will throw that error:
comment := Comment{Body: "This movie sucked"}
_, err := rek.Post("https://httpbin.org/post",
rek.Json(comment),
rek.FormData(map[string]string{"foo": "bar"}))
fmt.Println(err == rek.ErrRequestBodySetMultipleTimes) // true