gohttp

package module
v0.0.0-...-f1d050c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 29, 2016 License: MIT Imports: 14 Imported by: 0

README

gohttp

Travis-ci Status Coverage Status Software License Go Report Card GoDoc

A simple to use golang http client

Features

  • All HTTP methods support: GET/HEAD/POST/PUT/PATCH/DELETE/OPTIONS
  • Easy to set HTTP Headers
  • Query strings can be added through key-value pairs or struct easily
  • Extend url path whenever you want
  • Send form and json data in one line
  • Basic Auth right away
  • Read from response the easy way
  • Support proxy configuration
  • Allow set timeout at all levels
  • Automatically retry request, if you let it
  • Custom redirect policy
  • Perform hook functions
  • Session support, persistent response data, and reuse them in next request
  • More to come ...

Principles

  • Simple: the exposed interface should be simple and intuitive. After all, this is why gohttp is created
  • Consistent: Derived from net/http, gohttp tries to keep consistent with it as much as possible
  • Fully-Documented: along with the simple interface, documents and examples will be given to demostrate the full usage, pitfalls and best practices

Install

go get github.com/cizixs/gohttp

And then import the package in your code:

import "github.com/cizixs/gohttp"

Usage

Get a resource from url

gohttp provides shortcut to make simple GET quite straightforward:

resp, err := gohttp.Get("https://api.github.com/users/cizixs")

The above does the same thing as:

resp, err := gohttp.New().Get("https://api.github.com/users/cizixs")

In fact, this is exactly what it does behind the scene. gohttp.New() returns gohttp.Client struct, which gives you full control of the request which be sent.

Create url path on the fly

If url path can not decided until runtime or you want it be flexible, Path() method is here to help:

resp, err := gohttp.New().Path("/repos").Path("cizixs/gohttp/").Path("issues").Get("https://api.github.com/")

Or simply in one method:

resp, err := gohttp.New().Path("/repos", "cizixs/gohttp/", "issues").Get("https://api.github.com/")

Notice how gohttp handles the slash / appropriately no matter where it is placed(or not placed at all).

Pass arguments(query string) in URLs

There are often times you want to include query strings in url, handling this issue manually can be tiresome and boring. Not with gohttp:

gohttp.New().Path("/repos", "cizixs/gohttp/", "issues").
    Query("state", "open").Query("sort", "updated").Query("mentioned", "cizixs").
    Get("https://api.github.com/")

Think this is tedious too? Here comes the better part, you can pass a struct as query strings:

type issueOption struct {
	State     string `json:"state,omitempty"`
	Assignee  string `json:"assignee,omitempty"`
	Creator   string `json:"creator,omitempty"`
	Mentioned string `json:"mentioned,omitempty"`
	Labels    string `json:"labels,omitempty"`
	Sort      string `json:"sort,omitempty"`
	Rirection string `json:"direction,omitempty"`
	Since     string `json:"since,omitempty"`
}

i := &issueOption{
	State:     "open",
	Mentioned: "cizixs",
	Sort:      "updated",
}
resp, err := gohttp.New().Path("/repos", "cizixs/gohttp/", "issues").QueryStruct(i).Get("https://api.github.com/")
Custom Headers
gohttp.New().Header(key, value).Header(key, value).Get(url)

Or, simply pass all headers in a map:

gohttp.New().Headers(map[string]string).Get(url)
Post and PUT

Not only GET is simple, gohttp implements all other methods:

body := strings.NewReader("hello, gohttp!")
gohttp.New().Body(body).Post("https://httpbin.org/post")
gohttp.New().Body(body).Put("https://httpbin.org/put")

NOTE: The actual data sent is based on HTTP method the request finally fires. Anything not compliant with that METHOD will be ommited. For example, set data to a GET request has no effect, because it will not be used at all.

Post all kinds of data

When comes to sending data to server, POST might be the most frequently used method. Of all user cases, send form data and send json data comes to the top. gohttp tries to make these actions easy:

// send Form data
gohttp.New().Form("username", "cizixs").Form("password", "secret").Post("https://somesite.com/login")

// send json data
gohttp.New().Json(`{"Name":"Cizixs"}`).Post(url)         // use a marshalled json string

struct User{
    Name string `json:"name,omitempty"`
    Age int `json:"age,omitempty"`
}

user := &User{Name: "cizixs", Age: 22}
gohttp.New().JsonStruct(user).Post(url)   // use a struct and parse it to json
Basic Auth
gohttp.New().BasicAuth("username", "password").Get("https://api.github.com/users/")
Timeout

By default, net/http does not have timeout, will wait forever until response is returned. This can be a serious issue if server hangs, gohttp allows you to set a timeout limit, if response does not finish in time, an error will be returned.

gohttp.New().Timeout(100*time.Millisecond).Get("http://example.com")
Retries

Error happens! gohttp provides retry mechanism to automatically resend request when error happens. This is useful to avoid some unstable error like network temporary failure:

gohttp.New().Retries(3).Get("http://example.com")

By default, request is only sent only and all. If custom retry is set to less than one, default behavior will be used. The retry condition only means response error, not including 5XX error.

Upload file(s)

Upload files is simple too, multiple files can be uploaded in one request.

f, _ := os.Open(filePath)
gohttp.New().File(f io.Reader, "filename", "fieldname").Post(url)
Proxy

If you are sending request behind a proxy, you can do this:

gohttp.New().Proxy("http://127.0.0.1:4567").Get("http://target.com/cool")
Cookies

Access cookie from response is simple:

cookies := resp.Cookies()

gohttp.New().Cookie(cookie *http.Cookie).Cookie(cookie *http.Cookie).Get(url)
Response data as string

If the response contains string data, you can read it by:

resp, _ := gohttp.New().Get("http://someurl.com")
data, _ := resp.AsString()
Response data as bytes

If the response contains raw bytes, you can read it by:

resp, _ := gohttp.New().Get("http://someurl.com")
data, _ := resp.AsBytes()
Response data as json struct

If the response contains json struct, you can pass a struct to it, and gohttp will marshall it for you:

user := &User{}
resp, _ := gohttp.New().Get("http://someurl.com")
err := resp.AsJSON(user)
Reuse client

When developing complicated http client applications, it is common to interact with one remote server with some common settings, like url, basic auth, custom header, etc. gohttp provides New method for this kind of situation.

As stated in document:

New clones current client struct and returns it. This is useful to initialize some common parameters and send different requests with differenet paths/headers/timeout/retries...

For example:

c := gohttp.New().URL("https://api.github.com/")
c.BasicAuth("cizixs", "mypassword")
c.Timeout(3 * time.Second)
users, err := c.New().Path("/users/").Get()
repos, err := c.New().Path("/repos").Get()

Note: files, body and cookies value are copied so that if pointer value is used, base client and cloned client(s) will share the same instance, change on one side will take effect on the other side, and this might not as expected.

Debug mode

When developing http apps, it is often necessary to know the actual request and response sent for debugging or testing purpose. gohttp provides debug mode, which can be turned on by environment variable GOHTTP_DEBUG or Debug(bool) method:

resp, _ := gohttp.New().Debug(true).Get("http://someurl.com")

In debug mode, gohttp will print out each request and response in human-readble format.

A typical request:

POST / HTTP/1.1
Host: 127.0.0.1:43827
User-Agent: Go-http-client/1.1
Content-Length: 39
Content-Type: application/json
Accept-Encoding: gzip

{"title":"Test title","name":"cizixs"}

A typical response:

2016/11/29 18:30:59 HTTP/1.1 200 OK
Content-Length: 39
Content-Type: application/json; charset=utf-8
Date: Tue, 29 Nov 2016 10:30:59 GMT

{"age":24,"name":"cizixs"}

Contribution

Contributions are welcome!

  • Open a new issue if you find a bug or want to propose a feature
  • Create a Pull Request if you want to contribute to the code

Inspiration

This project is heavily influenced by many awesome projects out there, mainly the following:

License

MIT License

Documentation

Index

Constants

View Source
const DefaultTimeout = 3 * time.Second

DefaultTimeout defines the request timeout limit, avoiding client hanging when the remote server does not responde.

Variables

View Source
var DefaultClient = New()

DefaultClient provides a simple usable client, it is given for quick usage. For more control, please create a client manually.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the main struct that wraps net/http. It stores all necessary data for the request to be sent, include request method, url, body.

func New

func New() *Client

New returns a new GoClient with default values

func (*Client) BasicAuth

func (c *Client) BasicAuth(username, password string) *Client

BasicAuth allows simple username/password authentication

func (*Client) Body

func (c *Client) Body(body io.Reader) *Client

Body accepts `io.Reader`, will read data from it and use it as request body. This doee not set `Content-Type` header, so users should use `Header(key, value)` to specify it if necessary.

func (*Client) Cookie

func (c *Client) Cookie(cookie *http.Cookie) *Client

Cookie set client cookie, the argument is a standard `http.Cookie`

func (*Client) Debug

func (c *Client) Debug(debug bool) *Client

Debug sets the debug mode of go http. By default, debug mode is off.

This is only for testing and debugging purpose, it will print out detail information such as request and response dump string, and other logging lines.

If `GOHTTP_DEBUG` environment variable is set, `gohttp` will use the value. 1 for turn on debug mode, and others for turn off debug mode. Debug method overrides environment variable value.

func (*Client) Delete

func (c *Client) Delete(urls ...string) (*GoResponse, error)

Delete handles HTTP DELETE request

func (*Client) Do

func (c *Client) Do(method string, urls ...string) (*GoResponse, error)

Do takes HTTP and url, then makes the request, return the response. All other HTTP methods will call `Do` behind the scene, and it can be used directly to send the request. Custom HTTP method can be sent with this method. Accept optional url parameter, if multiple urls are given only the first one will be used.

func (*Client) File

func (c *Client) File(f *os.File, fileName, fieldName string) *Client

File adds a file in request body, and sends it to server Multiple files can be added by calling this method many times

func (*Client) Form

func (c *Client) Form(bodyForm interface{}) *Client

Form accepts a struct, uses it as body data, and sent it as application/www-x-form-urlencoded If the actual method does not support body or form data, such as `GET`, `HEAD`, it will be simply omitted.

func (*Client) Get

func (c *Client) Get(urls ...string) (*GoResponse, error)

Get handles HTTP GET request, and return response to user Note that the response is not `http.Response`, but a thin wrapper which does exactly what it used to and a little more.

func (*Client) Head

func (c *Client) Head(urls ...string) (*GoResponse, error)

Head handles HTTP HEAD request HEAD request works the same way as GET, except the response body is empty.

func (*Client) Header

func (c *Client) Header(key, value string) *Client

Header sets request header data

func (*Client) JSON

func (c *Client) JSON(bodyJSON string) *Client

JSON accepts a string as data, and sets it as body, and send it as application/json If the actual method does not support body or json data, such as `GET`, `HEAD`, it will be simply omitted.

func (*Client) JSONStruct

func (c *Client) JSONStruct(bodyJSON interface{}) *Client

JSONStruct accepts a struct as data, and sets it as body, and send it as application/json If the actual method does not support body or json data, such as `GET`, `HEAD`, it will be simply omitted.

func (*Client) New

func (c *Client) New() *Client

New clones current client struct and returns it This is useful to initialize some common parameters and send different requests with differenet paths/headers/...

For example:

c := gohttp.New().URL("https://api.github.com/")
c.BasicAuth("cizixs", "mypassword")
users, err := c.New().Path("/users/").Get()
repos, err := c.New().Path("/repos").Get()

Note that files, body and cookies value are copied if pointer value is used, base client and cloned client(s) will share the same instance, change on one side will take effect on the other side.

func (*Client) Options

func (c *Client) Options(urls ...string) (*GoResponse, error)

Options handles HTTP OPTIONS request

func (*Client) Patch

func (c *Client) Patch(urls ...string) (*GoResponse, error)

Patch handles HTTP PATCH request

func (*Client) Path

func (c *Client) Path(paths ...string) *Client

Path concatenates base url with resource path. Path can be with or without slash `/` at both end, it will be handled properly.

Usage:

gohttp.New().Path("users/cizixs").Get("someurl.com")

func (*Client) Post

func (c *Client) Post(urls ...string) (*GoResponse, error)

Post handles HTTP POST request

func (*Client) Proxy

func (c *Client) Proxy(proxy string) *Client

Proxy sets proxy server the client uses. If it is empty, `gohttp` will try to load proxy settings from environment variable

Usage:

gohttp.New().Proxy("http://127.0.0.1:4567").Get("http://someurl.com")

func (*Client) Put

func (c *Client) Put(urls ...string) (*GoResponse, error)

Put handles HTTP PUT request

func (*Client) Query

func (c *Client) Query(key, value string) *Client

Query set parameter query string

func (*Client) QueryStruct

func (c *Client) QueryStruct(queryStruct interface{}) *Client

QueryStruct parses a struct as query strings On how it works, please refer to github.com/google/go-querystring repo

func (*Client) Retries

func (c *Client) Retries(n int) *Client

Retries set how many request attempts will be conducted if error happens for a request. number <= 1 means no retries, send one request and finish.

func (*Client) TLSHandshakeTimeout

func (c *Client) TLSHandshakeTimeout(timeout time.Duration) *Client

TLSHandshakeTimeout sets the wait limit for performing TLS handshake. Default value for go1.6 is 10s, change this value to suit yourself.

func (*Client) Timeout

func (c *Client) Timeout(timeout time.Duration) *Client

Timeout sets the wait limit for a request to finish. This time includes connection time, redirectoin time, and read response body time. If request does not finish before the timeout, any ongoing action will be interrupted and an error will return

Usage:

gohttp.New().Timeout(time.Second * 10).Get(url)

func (*Client) URL

func (c *Client) URL(url string) *Client

URL sets the base url for the client, this can be overrided by the parameter of the final GET/POST/PUT method

type GoResponse

type GoResponse struct {
	*http.Response
}

GoResponse wraps the official `http.Response`, and provides more features. The main function is to parse resp body for users. In the future, it can gives more information, like request elapsed time, redirect history etc.

func Delete

func Delete(url string) (*GoResponse, error)

Delete provides a shortcut to send `DELETE` request It is used to remove a resource from server

func Get

func Get(url string) (*GoResponse, error)

Get provides a shortcut to send `GET` request

func Head(url string) (*GoResponse, error)

Head provides a shortcut to send `HEAD` request

func Options

func Options(url string) (*GoResponse, error)

Options provides a shortcut to send `OPTIONS` request

func Patch

func Patch(url string, data io.Reader) (*GoResponse, error)

Patch provides a shortcut to send `PATCH` request

func Post

func Post(url string, data io.Reader) (*GoResponse, error)

Post provides a shortcut to send `POST` request

func Put

func Put(url string, data io.Reader) (*GoResponse, error)

Put provides a shortcut to send `PUT` request

func (*GoResponse) AsBytes

func (resp *GoResponse) AsBytes() ([]byte, error)

AsBytes return the response body as byte slice An error will be returned if the body can not be read as bytes

func (*GoResponse) AsJSON

func (resp *GoResponse) AsJSON(v interface{}) error

AsJSON parses response body to a struct Usage:

user := &User{}
resp.AsJSON(user)
fmt.Printf("%s\n", user.Name)

func (*GoResponse) AsString

func (resp *GoResponse) AsString() (string, error)

AsString returns the response data as string An error wil bw returned if the body can not be read as string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL