leokhoa / rek

An easy HTTP client for Go. Inspired by the immortal Requests.

Home Page:https://pkg.go.dev/github.com/lucperkins/rek?tab=doc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rek

go.dev reference

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 as application/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 as multipart/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 as application/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

About

An easy HTTP client for Go. Inspired by the immortal Requests.

https://pkg.go.dev/github.com/lucperkins/rek?tab=doc

License:MIT License


Languages

Language:Go 100.0%