Documentation ¶
Overview ¶
Package requests is a high-level, API-centric HTTP client for Go projects. It is meant to provide a more comfortable mechanism to perform requests to HTTP APIs (rather than making general requests), and to prevent common mistakes made when using net/http directly.
With requests, one must not need to remember to read HTTP responses in full (so Go can reuse TCP connections), nor to close response bodies. Handling of JSON data - be it in requests or responses - is made easier by way of built-in encoders/decoders. An automatic retry mechanism is also included.
The library allows a "DRY" (Dont Repeat Yourself) approach to REST API usage by introducing API-specific dependencies into the client object. For example, authorization headers and response handlers can be set in the client object, and all generated requests will automatically include them.
Usage ¶
package main import ( "fmt" "net/http" "time" "github.com/ido50/requests" ) const apiURL = "https://my.api.com/v2" type RequestBody struct { Title string `json:"title"` Tags []string `json:"tags"` Publish bool `json:"publish"` } type ResponseBody struct { ID int64 `json:"id"` Date time.Time `json:"date"` } func main() { client := requests. NewClient(apiURL). Accept("application/json"). BasicAuth("user", "pass"). RetryLimit(3) var res ResponseBody err := client. NewRequest("POST", "/articles"). JSONBody(RequestBody{ Title: "Test Title", Tags: []string{"test", "stories"}, Publish: true, }). ExpectedStatus(http.StatusCreated). Into(&res). Run() if err != nil { panic(err) } fmt.Printf( "Created article %d on %s\n", res.ID, res.Date.Format(time.RFC3339), ) }
Index ¶
- Variables
- func MultipartFile(fieldname string, fsys fs.FS, filepath string) *multipartSrc
- func MultipartPart(fieldname, filename string, body interface{}) *multipartSrc
- type BodyHandlerFunc
- type BodyProcessorFunc
- type CompressionAlgorithm
- type ErrorHandlerFunc
- type HTTPClient
- func (cli *HTTPClient) Accept(accept string) *HTTPClient
- func (cli *HTTPClient) BasicAuth(user string, pass string, headerName ...string) *HTTPClient
- func (cli *HTTPClient) BodyHandler(handler BodyHandlerFunc) *HTTPClient
- func (cli *HTTPClient) CompressWith(alg CompressionAlgorithm) *HTTPClient
- func (cli *HTTPClient) CustomHTTPClient(cl *http.Client) *HTTPClient
- func (cli *HTTPClient) Do(req *http.Request) (*http.Response, error)
- func (cli *HTTPClient) ErrorHandler(handler ErrorHandlerFunc) *HTTPClient
- func (cli *HTTPClient) Header(key, value string) *HTTPClient
- func (cli *HTTPClient) Logger(logger *zap.Logger) *HTTPClient
- func (cli *HTTPClient) NewRequest(method, path string) *HTTPRequest
- func (cli *HTTPClient) NoTLSVerify(enabled bool) *HTTPClient
- func (cli *HTTPClient) RetryLimit(limit uint8) *HTTPClient
- func (cli *HTTPClient) SetRenegotiation(support tls.RenegotiationSupport) *HTTPClient
- func (cli *HTTPClient) SetTLS(certPEMBlock, keyPEMBlock, caCert []byte) *HTTPClient
- func (cli *HTTPClient) Timeout(dur time.Duration) *HTTPClient
- type HTTPRequest
- func (req *HTTPRequest) Accept(accept string) *HTTPRequest
- func (req *HTTPRequest) BasicAuth(user, pass string, headerName ...string) *HTTPRequest
- func (req *HTTPRequest) Body(body interface{}, contentType string) *HTTPRequest
- func (req *HTTPRequest) BodyHandler(handler BodyHandlerFunc) *HTTPRequest
- func (req *HTTPRequest) CompressWith(alg CompressionAlgorithm) *HTTPRequest
- func (req *HTTPRequest) Cookie(cookie *http.Cookie) *HTTPRequest
- func (req *HTTPRequest) CookiesInto(into *[]*http.Cookie) *HTTPRequest
- func (req *HTTPRequest) ErrorHandler(handler ErrorHandlerFunc) *HTTPRequest
- func (req *HTTPRequest) ExpectedStatus(status int) *HTTPRequest
- func (req *HTTPRequest) ExpectedStatuses(statuses ...int) *HTTPRequest
- func (req *HTTPRequest) FileBody(fsys fs.FS, filepath, contentType string) *HTTPRequest
- func (req *HTTPRequest) Header(key, value string) *HTTPRequest
- func (req *HTTPRequest) HeaderInto(header string, into *string) *HTTPRequest
- func (req *HTTPRequest) Into(into interface{}) *HTTPRequest
- func (req *HTTPRequest) JSONBody(body interface{}) *HTTPRequest
- func (req *HTTPRequest) MultipartBody(srcs ...*multipartSrc) *HTTPRequest
- func (req *HTTPRequest) QueryParam(key, value string) *HTTPRequest
- func (req *HTTPRequest) ReqBodyProcessor(fn BodyProcessorFunc) *HTTPRequest
- func (req *HTTPRequest) RetryLimit(limit uint8) *HTTPRequest
- func (req *HTTPRequest) Run() error
- func (req *HTTPRequest) RunContext(ctx context.Context) error
- func (req *HTTPRequest) SizeLimit(limit int64) *HTTPRequest
- func (req *HTTPRequest) StatusInto(into *int) *HTTPRequest
- func (req *HTTPRequest) Subscribe(ctx context.Context, messages chan []byte) error
- func (req *HTTPRequest) Timeout(dur time.Duration) *HTTPRequest
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSizeExceeded is the error returned when the size of an HTTP response // is larger than the set limit ErrSizeExceeded = errors.New("response size exceeded limit") // ErrTimeoutReached is the error returned when a request times out ErrTimeoutReached = errors.New("timeout reached") // ErrNotAPointer is an error returned when the target variable provided for // a request's Run method is not a pointer. ErrNotAPointer = errors.New("target variable is not a string pointer") // ErrUnsupportedCompression is an error returned when attempting to send // requests with a compression algorithm unsupported by the library ErrUnsupportedCompression = errors.New("unsupported compression algorithm") // ErrUnsupportedBody is an error returned when the value provided to the // request's Body method is unsupported, i.e. it is not a byte string, a // string, or a reader ErrUnsupportedBody = errors.New("unsupported body") )
var BaseDelay = 2 * time.Second
BaseDelay is the base delay for retrying requests. The library uses a backoff strategy, multiplying the delay between each attempt.
var DefaultTimeout = 2 * time.Minute
DefaultTimeout is the default timeout for requests made by the library. This can be overridden on a per-client and per-request basis.
Functions ¶
func MultipartFile ¶ added in v1.4.0
MultipartFile adds a new part to a multipart request from the provided file in a filesystem.
func MultipartPart ¶ added in v1.4.0
func MultipartPart(fieldname, filename string, body interface{}) *multipartSrc
MultipartPart adds a new part to a multipart request with the provided field name, file name, and body, which may be a []byte value, a string, or a reader.
Types ¶
type BodyHandlerFunc ¶
type BodyHandlerFunc func( httpStatus int, contentType string, body io.Reader, target interface{}, ) error
BodyHandlerFunc is a function that processes the response body and reads it into the target variable. It receives the status and content type of the response (the latter taken from the Content-Type header), the body reader, and the target variable (which is whatever was provided to the Into() method). It is not necessary to close the body or read it to its entirety.
type BodyProcessorFunc ¶ added in v1.6.0
BodyProcessorFunc is a function that reads a request's body as []byte from a provider reader, and writes it to a provided writer, potentially modifying it in the process. Such a function can be used to modify request bodies right before they are sent.
type CompressionAlgorithm ¶ added in v1.2.0
type CompressionAlgorithm string
CompressionAlgorithm denotes compression algorithms supported by the library for compressed request bodies.
const ( // CompressionAlgorithmNone represents no compression CompressionAlgorithmNone CompressionAlgorithm = "" // CompressionAlgorithmGzip represents the gzip compression algorithm CompressionAlgorithmGzip CompressionAlgorithm = "gzip" // CompressionAlgorithmDeflate represents the deflate compression algorithm CompressionAlgorithmDeflate CompressionAlgorithm = "deflate" )
type ErrorHandlerFunc ¶
ErrorHandlerFunc is similar to BodyHandler, but is called when requests generate an unsuccessful response (defined as anything that is not one of the expected statuses). It receives the same parameters except "target", and is expected to return a formatted error to the client
type HTTPClient ¶
type HTTPClient struct {
// contains filtered or unexported fields
}
HTTPClient represents a client for making requests to a web service or website. The client includes default options that are relevant for all requests (but can be overridden per-request).
func NewClient ¶
func NewClient(baseURL string) *HTTPClient
NewClient creates a new HTTP client for the API whose base URL is provided.
func (*HTTPClient) Accept ¶
func (cli *HTTPClient) Accept(accept string) *HTTPClient
Accept sets the response MIME type accepted by the client. Defaults to "application/json".
func (*HTTPClient) BasicAuth ¶
func (cli *HTTPClient) BasicAuth( user string, pass string, headerName ...string, ) *HTTPClient
BasicAuth sets basic authentication headers for all HTTP requests made by the client (requests can override this on an individual basis). If a header name is provided as the third argument, the authentication data will be set into that header instead of the standard "Authorization" header. This is mostly useful for Proxy-Authorization or custom headers.
func (*HTTPClient) BodyHandler ¶
func (cli *HTTPClient) BodyHandler(handler BodyHandlerFunc) *HTTPClient
BodyHandler sets a customer handler function for all requests made by the client. If provided, the handler will be called with the response status, content type, and body reader. This allows customizing the way response bodies are parsed, for example if the API does not use JSON serialization. Usually, the library's internal handler is sufficient for API usage.
func (*HTTPClient) CompressWith ¶ added in v1.2.0
func (cli *HTTPClient) CompressWith(alg CompressionAlgorithm) *HTTPClient
CompressWith sets a compression algorithm to apply to all request bodies. Compression is optional, in that if it fails, for any reason, requests will not fail, but instead be sent without compression. Note that there is no need to use this to support decompression of responses, the library handles decompressions automatically.
func (*HTTPClient) CustomHTTPClient ¶ added in v1.3.0
func (cli *HTTPClient) CustomHTTPClient(cl *http.Client) *HTTPClient
CustomHTTPClient sets a custom HTTP client for the underlaying net layer
func (*HTTPClient) Do ¶
Do performs an HTTP request represented as a net/http.Request object. This method was added so that an HTTPClient object will implement a common interface for HTTP clients. Generally, there is no need to use this method.
func (*HTTPClient) ErrorHandler ¶
func (cli *HTTPClient) ErrorHandler(handler ErrorHandlerFunc) *HTTPClient
ErrorHandler sets a custom handler function for all requests made by the client. Whenever a request is answered with an error response (or optionally in an unexpected status), the handler is called. This allows parsing API error structures so more information can be returned in case of failure.
func (*HTTPClient) Header ¶
func (cli *HTTPClient) Header(key, value string) *HTTPClient
Header sets a common header value for all requests made by the client.
func (*HTTPClient) Logger ¶
func (cli *HTTPClient) Logger(logger *zap.Logger) *HTTPClient
Logger sets the logger used by the library. Currently, requests uses go.uber.org/zap for logging purposes. All log messages are in the DEBUG level.
func (*HTTPClient) NewRequest ¶
func (cli *HTTPClient) NewRequest(method, path string) *HTTPRequest
NewRequest creates a new request object. Requests are progressively composed using a builder/method-chain pattern. The HTTP method and path within the API must be provided. Remember that the client already includes a base URL, so the request URL will be a concatenation of the base URL and the provided path. `path` can be empty.
func (*HTTPClient) NoTLSVerify ¶
func (cli *HTTPClient) NoTLSVerify(enabled bool) *HTTPClient
NoTLSVerify allows ignoring invalid or self-signed TLS certificates presented by HTTPS servers.
func (*HTTPClient) RetryLimit ¶
func (cli *HTTPClient) RetryLimit(limit uint8) *HTTPClient
RetryLimit sets the maximum amount of times requests that failed due to connection issues should be retried. Defaults to 0. Requests are retried with a backoff strategy, with the first retry attempt occurring two seconds after the original request, and the delay before each subsequent attempt is multiplied by two.
func (*HTTPClient) SetRenegotiation ¶
func (cli *HTTPClient) SetRenegotiation(support tls.RenegotiationSupport) *HTTPClient
SetRenegotiation allows setting the TLS renegotiation level. See crypto/tls for more information.
func (*HTTPClient) SetTLS ¶
func (cli *HTTPClient) SetTLS( certPEMBlock, keyPEMBlock, caCert []byte, ) *HTTPClient
SetTLS allows creating a custom TLS transport. Often combined with SetRenegotiation.
func (*HTTPClient) Timeout ¶
func (cli *HTTPClient) Timeout(dur time.Duration) *HTTPClient
Timeout sets the total timeout for requests made by the client. The default timeout is 2 minutes.
type HTTPRequest ¶
type HTTPRequest struct {
// contains filtered or unexported fields
}
HTTPRequest represents a single HTTP request to the web service defined in the client.
func (*HTTPRequest) Accept ¶
func (req *HTTPRequest) Accept(accept string) *HTTPRequest
Accept sets the accepted MIME type for the request. This takes precedence over the MIME type provided to the client object itself.
func (*HTTPRequest) BasicAuth ¶
func (req *HTTPRequest) BasicAuth( user, pass string, headerName ...string, ) *HTTPRequest
BasicAuth allows setting basic authentication header for the request. Usually, this will be done on the client object rather than the request object, but this method allows overriding authentication for specific requests.
func (*HTTPRequest) Body ¶
func (req *HTTPRequest) Body(body interface{}, contentType string) *HTTPRequest
ReaderBody sets a custom body for the request from an io.ReadCloser, io.Reader, []byte or string. The content type of the data must be provided.
func (*HTTPRequest) BodyHandler ¶
func (req *HTTPRequest) BodyHandler(handler BodyHandlerFunc) *HTTPRequest
BodyHandler sets a custom body handler for the request.
func (*HTTPRequest) CompressWith ¶ added in v1.2.0
func (req *HTTPRequest) CompressWith(alg CompressionAlgorithm) *HTTPRequest
CompressWith sets a compression algorithm to apply to all request bodies. Compression is optional, in that if it fails, for any reason, requests will not fail, but instead be sent without compression. Note that there is no need to use this to support decompression of responses, the library handles decompressions automatically.
func (*HTTPRequest) Cookie ¶
func (req *HTTPRequest) Cookie(cookie *http.Cookie) *HTTPRequest
Cookie sets a cookie for the request.
func (*HTTPRequest) CookiesInto ¶
func (req *HTTPRequest) CookiesInto(into *[]*http.Cookie) *HTTPRequest
CookiesInto allows storing cookies in the response into a slice of cookies. The same comments as for HeaderInto apply here as well.
func (*HTTPRequest) ErrorHandler ¶
func (req *HTTPRequest) ErrorHandler(handler ErrorHandlerFunc) *HTTPRequest
ErrorHandler sets a custom error handler for the request.
func (*HTTPRequest) ExpectedStatus ¶
func (req *HTTPRequest) ExpectedStatus(status int) *HTTPRequest
ExpectedStatus sets the HTTP status that the application expects to receive for the request. If the status received is different than the expected status, the library will return an error, and the error handler will be executed.
func (*HTTPRequest) ExpectedStatuses ¶
func (req *HTTPRequest) ExpectedStatuses(statuses ...int) *HTTPRequest
ExpectedStatuses is the same as ExpectedStatus, but allows setting multiple expected statuses.
func (*HTTPRequest) FileBody ¶ added in v1.4.0
func (req *HTTPRequest) FileBody(fsys fs.FS, filepath, contentType string) *HTTPRequest
FileBody sets the request body to be read from the provided filesystem and file path. The content type must be provided.
func (*HTTPRequest) Header ¶
func (req *HTTPRequest) Header(key, value string) *HTTPRequest
Header sets the value of a header for the request.
func (*HTTPRequest) HeaderInto ¶
func (req *HTTPRequest) HeaderInto(header string, into *string) *HTTPRequest
HeaderInto allows storing the value of a header from the response into a string variable. Since the requests library is made to quickly perform requests to REST APIs, and only a small number of response headers is usually read by application code (if at all), there is no response object that allows viewing headers. Therefore, any code that is interested in reading a response header must declare that in advance and provide a target variable.
func (*HTTPRequest) Into ¶
func (req *HTTPRequest) Into(into interface{}) *HTTPRequest
Into sets the target variable to which the response body should be parsed. If the API returns JSON, then this should be a pointer to a struct that represents the expected format. If using a custom body handler, this variable will be provided to the handler.
func (*HTTPRequest) JSONBody ¶
func (req *HTTPRequest) JSONBody(body interface{}) *HTTPRequest
JSONBody encodes the provided Go value into JSON and sets it as the request body.
func (*HTTPRequest) MultipartBody ¶ added in v1.4.0
func (req *HTTPRequest) MultipartBody(srcs ...*multipartSrc) *HTTPRequest
MultipartBody creates a multipart/form-data body from one or more sources, which may be file objects, bytes, strings or any reader.
func (*HTTPRequest) QueryParam ¶
func (req *HTTPRequest) QueryParam(key, value string) *HTTPRequest
QueryParam adds a query parameter and value to the request.
func (*HTTPRequest) ReqBodyProcessor ¶ added in v1.6.0
func (req *HTTPRequest) ReqBodyProcessor(fn BodyProcessorFunc) *HTTPRequest
ReqBodyProcessor adds a BodyProcessorFunc to the request. This function will be called right before the request is issued and can be used to modify the request body. The processor function MUST read AND write the entire body, and should not close it.
func (*HTTPRequest) RetryLimit ¶
func (req *HTTPRequest) RetryLimit(limit uint8) *HTTPRequest
RetryLimit sets the maximum amount of retries for the request. This takes precedence over the limit provided to the client object itself.
func (*HTTPRequest) Run ¶
func (req *HTTPRequest) Run() error
Run finalizes the request and executes it. The returned error will be `nil` only if the request was successfully created, sent and a successful (or expected) status code was returned from the server.
func (*HTTPRequest) RunContext ¶
func (req *HTTPRequest) RunContext(ctx context.Context) error
RunContext is the same as Run, but executes the request with the provided context value.
func (*HTTPRequest) SizeLimit ¶
func (req *HTTPRequest) SizeLimit(limit int64) *HTTPRequest
SizeLimit allows limiting the size of response bodies accepted by the client. If the response size is larger than the limit, `ErrSizeExceeded` will be returned.
func (*HTTPRequest) StatusInto ¶
func (req *HTTPRequest) StatusInto(into *int) *HTTPRequest
StatusInto allows storing the status of the response into a variable. The same comments as for HeaderInto apply here as well.
func (*HTTPRequest) Subscribe ¶ added in v1.5.0
func (req *HTTPRequest) Subscribe(ctx context.Context, messages chan []byte) error
Issue the request, expecting a text/event-stream response, and subscribe to that stream. Events (well, messages) from the server will be sent as-is to the provided channel. When all messages have been read, the channel is automatically closed.
func (*HTTPRequest) Timeout ¶
func (req *HTTPRequest) Timeout(dur time.Duration) *HTTPRequest
Timeout sets the timeout for the request. This takes precedence over the timeout provided to the client object itself.