httpsimp

package module
v2.0.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2018 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package httpsimp sends outgoing HTTP requests via a simple straightforward API distilled from many internal Golang projects at USA Today Network. It embraces Go stdlib types like url.Values and http.Header, provides composable building blocks for more complex use cases and doesn't try to be clever.

Call Get, Post or Put to send a request and parse the response in a single call:

var resp responseType
err := httpsimp.Get(baseURL, path, params, headers, client, httpsimp.JSON(&resp))

where httpsimp.JSON is a body parser function (we also provide PlainText, Bytes, Raw and None parsers, and you can define your own). See the example for more details.

You can adjust body parser parameters by passing additional options to body parser functions, like this:

httpsimp.JSON(nil, httpsimp.ContentType("application/something"))

Available options:

- httpsimp.StatusAny, httpsimp.Status4xx, httpsimp.Status4xx5xx, or a specific status like httpsimp.StatusOK or httpsimp.StatusSpec(http.StatusTeapot) will match only responses with the given status.

- httpsimp.ContentType("application/something") will match only response with the given content type.

- httpsimp.ContentType("") will match any content type (can be used to cancel default application/json filter used by JSON).

- httpsimp.ReturnError() results in a non-nil error returned.

Pass multiple parsers to handle alternative response types or non-2xx status codes:

var resp responseStruct
var bytes []byte
var e errorStruct
err := httpsimp.Get(...,
    httpsimp.JSON(&resp),
    httpsimp.Bytes(&bytes, httpsimp.ContentType("image/png")),
    httpsimp.JSON(&e, httpsimp.Status4xx5xx))

For more advanced requests, build http.Request yourself and call Perform:

var resp responseType
err := httpsimp.Perform(&http.Request{
    Method: http.MethodPut,
    URL:    httpsimp.URL(baseURL, path, params),
    Header: http.Header{...},
    Body:   []byte{"whatever"},
}, httpsimp.JSON(&resp))

Use URL func to concatenate a URL and include query params, and EncodeForm helper to generate application/x-www-form-urlencoded bodies.

Finally, if http.Client.Do doesn't rock your boat, you're free to build and execute a request through whatever means necessary and then call Parse to verify the response status code and handle the body:

req := EncodeForm(&http.Request{
    Method: http.MethodPost,
    URL:    httpsimp.URL(baseURL, path, nil),
    Header: http.Header{...},
}, url.Params{...})

httpResp, err := whatever.Do(req)
if err != nil { ... }

var resp responseType
err = httpsimp.Parse(httpResp, httpsimp.JSON(&resp))

To handle HTTP basic authentication, use BasicAuthValue helper:

err := httpsimp.Get("...", "...", url.Values{...}, http.Header{
    httpsimp.AuthorizationHeader: []string{httpsimp.BasicAuthValue("user", "pw")},
}, httpsimp.JSON, &resp)
Example
var resp exampleResponse
// url.Values is just a map[string][]string
err := httpsimp.Get(endpointURL, "examples/foo.json", url.Values{
	"param1": []string{"value1"},
	"param2": []string{"value2"},
}, nil, http.DefaultClient, httpsimp.JSON(&resp))

if err != nil {
	log.Fatal(err)
}
log.Printf("foo = %#v", resp)
Example (CustomHeaders)
var resp exampleResponse
// url.Values and http.Header are both just map[string][]string
err := httpsimp.Get(endpointURL, "examples/foo.json", url.Values{
	"param1": []string{"value1"},
	"param2": []string{"value2"},
}, http.Header{
	"X-Powered-By":               []string{"Golang"},
	httpsimp.AuthorizationHeader: []string{httpsimp.BasicAuthValue("user", "secret")},
}, http.DefaultClient, httpsimp.JSON(&resp))

if err != nil {
	log.Fatal(err)
}
log.Printf("foo = %#v", resp)

Index

Examples

Constants

View Source
const (
	// ContentTypeJSON is "application/json"
	ContentTypeJSON = "application/json"

	// ContentTypeTextPlain is "text/plain"
	ContentTypeTextPlain = "text/plain"

	// ContentTypeFormURLEncoded is "application/x-www-form-urlencoded"
	ContentTypeFormURLEncoded = "application/x-www-form-urlencoded"
)
View Source
const (
	// StatusNone matches no status code and is a zero value of StatusSpec.
	StatusNone StatusSpec = 0

	// StatusAny matches all status codes.
	StatusAny StatusSpec = -1500

	// Status1xx matches all 1xx status codes.
	Status1xx StatusSpec = -100

	// Status2xx matches all 2xx status codes.
	Status2xx StatusSpec = -200

	// Status3xx matches all 3xx status codes.
	Status3xx StatusSpec = -300

	// Status4xx matches all 4xx status codes.
	Status4xx StatusSpec = -400

	// Status4xx matches all 4xx status codes.
	Status5xx StatusSpec = -500

	// Status4xx5xx matches all 4xx and 5xx status codes.
	Status4xx5xx StatusSpec = -900

	StatusOK             = StatusSpec(http.StatusOK)
	StatusCreated        = StatusSpec(http.StatusCreated)
	StatusAccepted       = StatusSpec(http.StatusAccepted)
	StatusNoContent      = StatusSpec(http.StatusNoContent)
	StatusPartialContent = StatusSpec(http.StatusPartialContent)

	StatusUnauthorized = StatusSpec(http.StatusUnauthorized)
	StatusForbidden    = StatusSpec(http.StatusForbidden)
	StatusNotFound     = StatusSpec(http.StatusNotFound)
)
View Source
const (
	// AuthorizationHeader is the "Authorization" HTTP header
	AuthorizationHeader = "Authorization"
)

Variables

This section is empty.

Functions

func BasicAuthValue

func BasicAuthValue(username, password string) string

BasicAuthValue returns an Authorization header value for HTTP Basic authentication method with the given username and password, i.e. it returns:

"Basic " + base64(username + ":" + password)

Use AuthorizationHeader constant for the header name.

func EncodeForm

func EncodeForm(r *http.Request, params url.Values) *http.Request

EncodeForm encodes the given params into application/x-www-form-urlencoded format and sets the body and Content-Type on the given request.

To properly handle HTTP redirects, both Body and GetBody are set.

func Get

func Get(base, path string, params url.Values, headers http.Header, client HTTPClient, parsers ...Parser) error

Get builds a GET request with the given URL, parameters and headers, executes it via http.DefaultClient.Do and handles the body using the specified parser function.

base and path are concatenated to form a URL; at least one of them must be provided, but the other one can be an empty string. The resulting URL must be valid and parsable via net/url, otherwise panic ensues.

url.Values and http.Header are just maps that can be provided in place, no need to use their fancy Set or Add methods.

parser can be either JSON, PlainText, Bytes, Raw or None from this package, or your own custom parser function; it will be called with *http.Response and the result you pass in.

func Is4xx

func Is4xx(err error) bool

func Is5xx

func Is5xx(err error) bool

func Parse

func Parse(resp *http.Response, parsers ...Parser) error

func Perform

func Perform(r *http.Request, client HTTPClient, parsers ...Parser) error

Perform executes the given request via the given http.Client and handles the body using the specified parser function.

parser can be either JSON, Bytes, Raw or None from this package, or your own custom parser function; it will be called with *http.Response and the result you pass in.

func Post

func Post(base, path string, params url.Values, headers http.Header, client HTTPClient, parsers ...Parser) error

Post builds a POST request with the given URL, headers and body (which contains the given params in application/x-www-form-urlencoded format), executes it via http.DefaultClient.Do and handles the body using the specified parser function.

base and path are concatenated to form a URL; at least one of them must be provided, but the other one can be an empty string. The resulting URL must be valid and parsable via net/url, otherwise panic ensues.

url.Values and http.Header are just maps that can be provided in place, no need to use their fancy Set or Add methods.

parser can be either JSON, Bytes, Raw or None from this package, or your own custom parser function; it will be called with *http.Response and the result you pass in.

func Put

func Put(base, path string, params url.Values, headers http.Header, client HTTPClient, parsers ...Parser) error

Put builds a PUT request with the given URL, headers and body (which contains the given params in application/x-www-form-urlencoded format), executes it via the given http.Client and handles the body using the specified parser function.

base and path are concatenated to form a URL; at least one of them must be provided, but the other one can be an empty string. The resulting URL must be valid and parsable via net/url, otherwise panic ensues.

url.Values and http.Header are just maps that can be provided in place, no need to use their fancy Set or Add methods.

parser can be either JSON, Bytes, Raw or None from this package, or your own custom parser function; it will be called with *http.Response and the result you pass in.

func StatusCode

func StatusCode(err error) int

func URL

func URL(base, path string, params url.Values) *url.URL

URL returns a *url.URL (conveniently suitable for http.Request's URL field) concatenating the two given URL strings and optionally appending a query string with the given params.

base and path are concatenated to form a URL; at least one of them must be provided, but the other one can be an empty string. The resulting URL must be valid and parsable via net/url, otherwise panic ensues.

url.Values and http.Header are just maps that can be provided in place, no need to use their fancy Set or Add methods.

Types

type HTTPClient

type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}

HTTPClient is an interface implemented by *http.Client, requiring only the Do method. Instead of accepting *http.Client, the methods in this package accept HTTPClients for extra flexibility.

type ParseOption

type ParseOption interface {
	// contains filtered or unexported methods
}
var ReturnError ParseOption = matchOptionFunc(func(m *Parser) {
	m.retErr = true
})

func ContentType

func ContentType(ctype string) ParseOption

type Parser

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

func Bytes

func Bytes(result *[]byte, mopt ...ParseOption) Parser

Bytes is a Parser function that verifies the response status code and reads the entire body into a byte array; result must be a pointer to a []byte variable.

func JSON

func JSON(result interface{}, mopt ...ParseOption) Parser

JSON is a Parser function that verifies the response status code and content type (which must be ContentTypeJSON) and unmarshals the body into the result variable (which can be anything that you'd pass to json.Unmarshal).

func MakeParser

func MakeParser(defaultCtype string, mopt []ParseOption, bodyParser func(resp *http.Response) (interface{}, error)) Parser

func None

func None(mopt ...ParseOption) Parser

None is a Parser function that verifies the response status code and discards the response body; result argument is ignored and should be nil.

A typical use would be to pass this function into Get, Post or Perform, but you can also call it directly.

func PlainText

func PlainText(result *string, mopt ...ParseOption) Parser

PlainText is a Parser function that verifies the response status code and reads the entire body into a string; result must be a pointer to a string variable.

func Raw

func Raw(ptr **http.Response, mopt ...ParseOption) Parser

Raw is a Parser function that verifies the response status code and returns the raw *http.Response; result must be a pointer to *http.Response variable.

type StatusSpec

type StatusSpec int

func (StatusSpec) Matches

func (desired StatusSpec) Matches(actual int) bool

Matches returns whether the given actual HTTP status code matches the desired status code spec, which may be a specific status code or one of special constants: StatusNone (won't match anything), Status1xx, Status2xx, Status3xx, Status4xx, Status5xx.

Jump to

Keyboard shortcuts

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