got

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

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

Go to latest
Published: Apr 1, 2019 License: MPL-2.0 Imports: 11 Imported by: 96

README

Got - HTTP API Calls

Package got is a super simple net/http wrapper that does the right thing for most JSON REST APIs specifically adding:

  • Retry logic with exponential back-off,
  • Reading of body with a MaxSize to avoid running out of memory,
  • Timeout after 30 seconds.
g := got.New()
response, err := g.NewRequest("PUT", url, []byte("...")).Send()
if err == nil {
  // handle error
}

// Make a GET request
response, err := g.NewRequest("GET", url, nil).Send()
// or short hand
response, err := g.Get(url).Send()

// Send JSON in a request
request := g.NewRequest("PUT", url, []byte(`{"key": "value"}`))
request.Header.Set("Content-Type": "application/json")
// or short hand
request := g.Put(url, nil)
err := request.JSON(map[string]{"key": "value"})

// Disable retries for a request
request := g.NewRequest("POST", url, []byte(`{"key": "value"}`))
request.Retries = 0  // Defaults to 5

// Disable retries for all requests
g.Retries = 0

For more details see: godoc.org/github.com/taskcluster/go-got

Documentation

Overview

Package got is a super simple net/http wrapper that does the right thing for most JSON REST APIs specifically adding:

  • Retry logic with exponential back-off,
  • Reading of body with a MaxSize to avoid running out of memory,
  • Timeout after 30 seconds.

Send a request with retries like this:

g := got.New()
response, err := g.NewRequest("PUT", url, []byte("...")).Send()
if err == nil {
  // handle error
}
json.Unmarshal(response.Body, &MyObject)

This package will never support streaming requests. For small requests like JSON it is often best to buffer the entire body before parsing it. As slow parsing using a unbuffered decoder can slowdown the request.

It is also much easier to send requests and handled responses with small JSON payloads if there is no dealing with streaming. Streaming particularly complicates retries. If you need to stream the request body, DO NOT use this package.

Index

Constants

This section is empty.

Variables

View Source
var DefaultBackOff = &BackOff{
	DelayFactor:         100 * time.Millisecond,
	RandomizationFactor: 0.25,
	MaxDelay:            30 * time.Second,
}

DefaultBackOff is a simple exponential backoff with delays as follows:

  1. 400, range: [300; 500]
  2. 100, range: [75; 125]
  3. 200, range: [150; 250]
  4. 800, range: [600; 1000]
View Source
var DefaultClient = &http.Client{
	Timeout: 30 * time.Second,
}

DefaultClient is the default client used by got.New().

Most importantly it has a sane timeout. Which is what you'll want for REST API calls.

View Source
var ErrResponseTooLarge = errors.New("Response body is larger than MaxSize")

ErrResponseTooLarge is used to indicate that the response was larger than the safety limit at MaxSize (defined the request)

Functions

func DefaultIsTransient

func DefaultIsTransient(response BadResponseCodeError) bool

DefaultIsTransient determines if an error is transient or persistent.

This is the default implementation of Got.IsTransient, if nothing else is specified. By implementing a custom variant of this method and specifying on Got, it is possible to decide which 5xx error to retry. Default implementation is to retry any 5xx error.

func DefaultMakeRequest

func DefaultMakeRequest(r *Request) (*http.Request, error)

DefaultMakeRequest creates a http.Request from a got.Request.

This is the default implementation of Got.MakeRequest, if nothing else is specified. MakeRequest can be specified, for special use-cases such as generating a new Authorization header for each retry.

Types

type BackOff

type BackOff struct {
	DelayFactor         time.Duration
	RandomizationFactor float64
	MaxDelay            time.Duration
}

BackOff configuration for retries

func (BackOff) Delay

func (b BackOff) Delay(attempts int) time.Duration

Delay computes the delay for exponential back-off given the number of attempts, tried so far. Use attempts = 0 for the first try, attempts = 1 for the first retry and attempts = 2 for the second retry...

type BadResponseCodeError

type BadResponseCodeError struct {
	*Response
}

BadResponseCodeError is used to indicate a non-2xx status code

func (BadResponseCodeError) Error

func (e BadResponseCodeError) Error() string

type Got

type Got struct {
	Client      *http.Client
	BackOff     *BackOff
	Retries     int
	IsTransient func(BadResponseCodeError) bool
	Log         Logger
	MaxSize     int64
	MakeRequest func(*Request) (*http.Request, error)
}

Got is a simple HTTP client

func New

func New() *Got

New returns a new Got client with sane defaults for most small REST API requests.

This includes:

  • Max 5 retries,
  • Exponential back-off: 100, 200, 400, 800 ms with 25% randomization
  • Retry any 5xx error,
  • ErrResponseTooLarge if response body is larger than 10 MiB,
  • Timeout at 30 seconds,

Notice, this different from the defaults you will get with a zero-value Got{} structure.

Note: Depending on the API you are calling you may not wish to use retries, for verbs like POST, PATCH, etc. that aren't idemponent. In that case, you just set Got.Retries = 0, for the instance used for non-idemponent requests.

func (*Got) Delete

func (g *Got) Delete(url string) *Request

Delete returns a new DELETE request with settings from Got

func (*Got) Get

func (g *Got) Get(url string) *Request

Get returns a new GET request with settings from Got

func (*Got) Head

func (g *Got) Head(url string) *Request

Head returns a new HEAD request with settings from Got

func (*Got) NewRequest

func (g *Got) NewRequest(method string, url string, body []byte) *Request

NewRequest returns a new request with settings from Got

func (*Got) Patch

func (g *Got) Patch(url string, body []byte) *Request

Patch returns a new PATCH request with settings from Got

func (*Got) Post

func (g *Got) Post(url string, body []byte) *Request

Post returns a new POST request with settings from Got

func (*Got) Put

func (g *Got) Put(url string, body []byte) *Request

Put returns a new PUT request with settings from Got

type Logger

type Logger interface {
	Println(v ...interface{})
}

Logger is a simple logging interface. This is implicitly implemented by the builtin log package as well as logrus.

type Request

type Request struct {
	Got
	Method string
	URL    string
	Header http.Header
	Body   []byte
	context.Context
}

A Request as is ready to be sent

func (*Request) JSON

func (r *Request) JSON(object interface{}) error

JSON sets the body to a JSON object and sets Content-Type to application/json

func (*Request) Send

func (r *Request) Send() (*Response, error)

Send will execute the HTTP request

func (*Request) String

func (r *Request) String() string

String returns a string representation of the request for debugging

func (*Request) WithContext

func (r *Request) WithContext(ctx context.Context) *Request

WithContext returns a new request with the Context property set

type Response

type Response struct {
	StatusCode int
	Header     http.Header
	Body       []byte
	Attempts   int
}

A Response as received

func (*Response) String

func (r *Response) String() string

String returns a string representation of the response for debugging

Jump to

Keyboard shortcuts

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