Documentation ¶
Overview ¶
Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/) generated Go code.
The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, and Responding. A typical pattern is:
req, err := Prepare(&http.Request{}, token.WithAuthorization()) resp, err := Send(req, WithLogging(logger), DoErrorIfStatusCode(http.StatusInternalServerError), DoCloseIfError(), DoRetryForAttempts(5, time.Second)) err = Respond(resp, ByClosing())
Each phase relies on decorators to modify and / or manage processing. Decorators may first modify and then pass the data along, pass the data first and then modify the result, or wrap themselves around passing the data (such as a logger might do). Decorators run in the order provided. For example, the following:
req, err := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/"), WithPath("a"), WithPath("b"), WithPath("c"))
will set the URL to:
https://microsoft.com/a/b/c
Preparers and Responders may be shared and re-used (assuming the underlying decorators support sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, all bound together by means of input / output channels.
Decorators hold their passed state within a closure (such as the path components in the example above). Be careful to share Preparers and Responders only in a context where such held state applies. For example, it may not make sense to share a Preparer that applies a query string from a fixed set of values. Similarly, sharing a Responder that reads the response body into a passed struct (e.g., ByUnmarshallingJson) is likely incorrect.
Lastly, the Swagger specification (https://swagger.io) that drives AutoRest (https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure correct parsing and formatting.
Errors raised by autorest objects and methods will conform to the autorest.Error interface.
See the included examples for more detail. For details on the suggested use of this package by generated clients, see the Client described below.
Index ¶
- Constants
- func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error)
- func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) error
- func ExtractHeader(header string, resp *http.Response) []string
- func ExtractHeaderValue(header string, resp *http.Response) string
- func GetLocation(resp *http.Response) string
- func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration
- func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error)
- func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error)
- func Respond(r *http.Response, decorators ...RespondDecorator) error
- func ResponseHasStatusCode(resp *http.Response, codes ...int) bool
- func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error)
- func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error)
- func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser
- func Version() string
- type Authorizer
- type Client
- type Decoder
- type DetailedError
- func NewError(packageType string, method string, message string, args ...interface{}) DetailedError
- func NewErrorWithError(original error, packageType string, method string, resp *http.Response, ...) DetailedError
- func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, ...) DetailedError
- type EncodedAs
- type LoggingInspector
- type NullAuthorizer
- type PrepareDecorator
- func AsContentType(contentType string) PrepareDecorator
- func AsDelete() PrepareDecorator
- func AsFormURLEncoded() PrepareDecorator
- func AsGet() PrepareDecorator
- func AsHead() PrepareDecorator
- func AsJSON() PrepareDecorator
- func AsOptions() PrepareDecorator
- func AsPatch() PrepareDecorator
- func AsPost() PrepareDecorator
- func AsPut() PrepareDecorator
- func WithBaseURL(baseURL string) PrepareDecorator
- func WithBearerAuthorization(token string) PrepareDecorator
- func WithBool(v bool) PrepareDecorator
- func WithEscapedPathParameters(pathParameters map[string]interface{}) PrepareDecorator
- func WithFloat32(v float32) PrepareDecorator
- func WithFloat64(v float64) PrepareDecorator
- func WithFormData(v url.Values) PrepareDecorator
- func WithHeader(header string, value string) PrepareDecorator
- func WithInt32(v int32) PrepareDecorator
- func WithInt64(v int64) PrepareDecorator
- func WithJSON(v interface{}) PrepareDecorator
- func WithMethod(method string) PrepareDecorator
- func WithNothing() PrepareDecorator
- func WithPath(path string) PrepareDecorator
- func WithPathParameters(pathParameters map[string]interface{}) PrepareDecorator
- func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator
- func WithString(v string) PrepareDecorator
- func WithUserAgent(ua string) PrepareDecorator
- type Preparer
- type PreparerFunc
- type RespondDecorator
- func ByClosing() RespondDecorator
- func ByClosingIfError() RespondDecorator
- func ByCopying(b *bytes.Buffer) RespondDecorator
- func ByIgnoring() RespondDecorator
- func ByUnmarshallingJSON(v interface{}) RespondDecorator
- func ByUnmarshallingXML(v interface{}) RespondDecorator
- func WithErrorUnlessOK() RespondDecorator
- func WithErrorUnlessStatusCode(codes ...int) RespondDecorator
- type Responder
- type ResponderFunc
- type Response
- type SendDecorator
- func AfterDelay(d time.Duration) SendDecorator
- func AsIs() SendDecorator
- func DoCloseIfError() SendDecorator
- func DoErrorIfStatusCode(codes ...int) SendDecorator
- func DoErrorUnlessStatusCode(codes ...int) SendDecorator
- func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator
- func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator
- func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator
- func WithLogging(logger *log.Logger) SendDecorator
- type Sender
- type SenderFunc
Examples ¶
- ByUnmarshallingJSON
- ByUnmarshallingXML
- CreatePreparer
- CreatePreparer (Chain)
- CreatePreparer (Multiple)
- DoErrorIfStatusCode
- DoRetryForAttempts
- Prepare
- PrepareDecorator
- PrepareDecorator (Pre)
- SendWithSender
- WithBaseURL
- WithErrorUnlessOK
- WithEscapedPathParameters
- WithFormData
- WithHeader
- WithJSON
- WithPathParameters
- WithQueryParameters
Constants ¶
const ( // HeaderLocation specifies the HTTP Location header. HeaderLocation = "Location" // HeaderRetryAfter specifies the HTTP Retry-After header. HeaderRetryAfter = "Retry-After" )
const ( // DefaultPollingDelay is a reasonable delay between polling requests. DefaultPollingDelay = 60 * time.Second // DefaultPollingDuration is a reasonable total polling duration. DefaultPollingDuration = 15 * time.Minute )
const (
// UndefinedStatusCode is used when HTTP status code is not available for an error.
UndefinedStatusCode = 0
)
Variables ¶
This section is empty.
Functions ¶
func CopyAndDecode ¶
CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy is especially useful if there is a chance the data will fail to decode. encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v is the decoding destination.
func DelayForBackoff ¶
DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of passed attempt (i.e., an exponential backoff delay). Backoff may be zero. The delay may be canceled by closing the passed channel.
func ExtractHeader ¶
ExtractHeader extracts all values of the specified header from the http.Response. It returns an empty string slice if the passed http.Response is nil or the header does not exist.
func ExtractHeaderValue ¶
ExtractHeaderValue extracts the first value of the specified header from the http.Response. It returns an empty string if the passed http.Response is nil or the header does not exist.
func GetLocation ¶
GetLocation retrieves the URL from the Location header of the passed response.
func GetRetryAfter ¶
GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If the header is absent or is malformed, it will return the supplied default delay time.Duration.
func NewPollingRequest ¶
NewPollingRequest allocates and returns a new http.Request to poll for the passed response.
func Prepare ¶
Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators. It creates a Preparer from the decorators which it then applies to the passed http.Request.
Example ¶
Create and prepare an http.Request in one call
r, err := Prepare(&http.Request{}, AsGet(), WithBaseURL("https://microsoft.com/"), WithPath("a/b/c/")) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Printf("%s %s", r.Method, r.URL) }
Output: GET https://microsoft.com/a/b/c/
func Respond ¶
func Respond(r *http.Response, decorators ...RespondDecorator) error
Respond accepts an http.Response and a, possibly empty, set of RespondDecorators. It creates a Responder from the decorators it then applies to the passed http.Response.
func ResponseHasStatusCode ¶
ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set and false otherwise.
func Send ¶
Send sends, by means of the default http.Client, the passed http.Request, returning the http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which it will apply the http.Client before invoking the Do method.
Send is a convenience method and not recommended for production. Advanced users should use SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client).
Send will not poll or retry requests.
func SendWithSender ¶
SendWithSender sends the passed http.Request, through the provided Sender, returning the http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which it will apply the http.Client before invoking the Do method.
SendWithSender will not poll or retry requests.
Example ¶
r := mocks.NewResponseWithStatus("202 Accepted", http.StatusAccepted) mocks.SetAcceptedHeaders(r) client := mocks.NewSender() client.AppendAndRepeatResponse(r, 10) logger := log.New(os.Stdout, "autorest: ", 0) na := NullAuthorizer{} req, _ := Prepare(&http.Request{}, AsGet(), WithBaseURL("https://microsoft.com/a/b/c/"), na.WithAuthorization()) r, _ = SendWithSender(client, req, WithLogging(logger), DoErrorIfStatusCode(http.StatusAccepted), DoCloseIfError(), DoRetryForAttempts(5, time.Duration(0))) Respond(r, ByClosing())
Output: autorest: Sending GET https://microsoft.com/a/b/c/ autorest: GET https://microsoft.com/a/b/c/ received 202 Accepted autorest: Sending GET https://microsoft.com/a/b/c/ autorest: GET https://microsoft.com/a/b/c/ received 202 Accepted autorest: Sending GET https://microsoft.com/a/b/c/ autorest: GET https://microsoft.com/a/b/c/ received 202 Accepted autorest: Sending GET https://microsoft.com/a/b/c/ autorest: GET https://microsoft.com/a/b/c/ received 202 Accepted autorest: Sending GET https://microsoft.com/a/b/c/ autorest: GET https://microsoft.com/a/b/c/ received 202 Accepted
func TeeReadCloser ¶
func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser
TeeReadCloser returns a ReadCloser that writes to w what it reads from rc. It utilizes io.TeeReader to copy the data read and has the same behavior when reading. Further, when it is closed, it ensures that rc is closed as well.
Types ¶
type Authorizer ¶
type Authorizer interface {
WithAuthorization() PrepareDecorator
}
Authorizer is the interface that provides a PrepareDecorator used to supply request authorization. Most often, the Authorizer decorator runs last so it has access to the full state of the formed HTTP request.
type Client ¶
type Client struct { Authorizer Authorizer Sender Sender RequestInspector PrepareDecorator ResponseInspector RespondDecorator // PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header PollingDelay time.Duration // PollingDuration sets the maximum polling time after which an error is returned. PollingDuration time.Duration // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent // through the Do method. UserAgent string }
Client is the base for autorest generated clients. It provides default, "do nothing" implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the standard, undecorated http.Client as a default Sender.
Generated clients should also use Error (see NewError and NewErrorWithError) for errors and return responses that compose with Response.
Most customization of generated clients is best achieved by supplying a custom Authorizer, custom RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence sending the request by providing a decorated Sender.
func NewClientWithUserAgent ¶
NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed string.
func (Client) ByInspecting ¶
func (c Client) ByInspecting() RespondDecorator
ByInspecting is a convenience method that passes the response to the supplied ResponseInspector, if present, or returns the ByIgnoring RespondDecorator otherwise.
func (Client) Do ¶
Do implements the Sender interface by invoking the active Sender after applying authorization. If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent is set, apply set the User-Agent header.
func (Client) WithAuthorization ¶
func (c Client) WithAuthorization() PrepareDecorator
WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer.
func (Client) WithInspection ¶
func (c Client) WithInspection() PrepareDecorator
WithInspection is a convenience method that passes the request to the supplied RequestInspector, if present, or returns the WithNothing PrepareDecorator otherwise.
type Decoder ¶
type Decoder interface {
Decode(v interface{}) error
}
Decoder defines the decoding method json.Decoder and xml.Decoder share
type DetailedError ¶
type DetailedError struct { Original error // PackageType is the package type of the object emitting the error. For types, the value // matches that produced the the '%T' format specifier of the fmt package. For other elements, // such as functions, it is just the package name (e.g., "autorest"). PackageType string // Method is the name of the method raising the error. Method string // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error. StatusCode int // Message is the error message. Message string }
DetailedError encloses a error with details of the package, method, and associated HTTP status code (if any).
func NewError ¶
func NewError(packageType string, method string, message string, args ...interface{}) DetailedError
NewError creates a new Error conforming object from the passed packageType, method, and message. message is treated as a format string to which the optional args apply.
func NewErrorWithError ¶
func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError
NewErrorWithError creates a new Error conforming object from the passed packageType, method, statusCode of the given resp (UndefinedStatusCode if resp is nil), message, and original error. message is treated as a format string to which the optional args apply.
func NewErrorWithResponse ¶
func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError
NewErrorWithResponse creates a new Error conforming object from the passed packageType, method, statusCode of the given resp (UndefinedStatusCode if resp is nil), and message. message is treated as a format string to which the optional args apply.
func (DetailedError) Error ¶
func (e DetailedError) Error() string
Error returns a formatted containing all available details (i.e., PackageType, Method, StatusCode, Message, and original error (if any)).
type EncodedAs ¶
type EncodedAs string
EncodedAs is a series of constants specifying various data encodings
type LoggingInspector ¶
LoggingInspector implements request and response inspectors that log the full request and response to a supplied log.
func (LoggingInspector) ByInspecting ¶
func (li LoggingInspector) ByInspecting() RespondDecorator
ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The body is restored after being emitted.
Note: Since it reads the entire Body, this decorator should not be used where body streaming is important. It is best used to trace JSON or similar body values.
func (LoggingInspector) WithInspection ¶
func (li LoggingInspector) WithInspection() PrepareDecorator
WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The body is restored after being emitted.
Note: Since it reads the entire Body, this decorator should not be used where body streaming is important. It is best used to trace JSON or similar body values.
type NullAuthorizer ¶
type NullAuthorizer struct{}
NullAuthorizer implements a default, "do nothing" Authorizer.
func (NullAuthorizer) WithAuthorization ¶
func (na NullAuthorizer) WithAuthorization() PrepareDecorator
WithAuthorization returns a PrepareDecorator that does nothing.
type PrepareDecorator ¶
PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the http.Request and pass it along or, first, pass the http.Request along then affect the result.
Example ¶
PrepareDecorators wrap and invoke a Preparer. Most often, the decorator invokes the passed Preparer and decorates the response.
path := "a/b/c/" pd := func() PrepareDecorator { return func(p Preparer) Preparer { return PreparerFunc(func(r *http.Request) (*http.Request, error) { r, err := p.Prepare(r) if err == nil { if r.URL == nil { return r, fmt.Errorf("ERROR: URL is not set") } r.URL.Path += path } return r, err }) } } r, _ := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/"), pd()) fmt.Printf("Path is %s\n", r.URL)
Output: Path is https://microsoft.com/a/b/c/
Example (Pre) ¶
PrepareDecorators may also modify and then invoke the Preparer.
pd := func() PrepareDecorator { return func(p Preparer) Preparer { return PreparerFunc(func(r *http.Request) (*http.Request, error) { r.Header.Add(http.CanonicalHeaderKey("ContentType"), "application/json") return p.Prepare(r) }) } } r, _ := Prepare(&http.Request{Header: http.Header{}}, pd()) fmt.Printf("ContentType is %s\n", r.Header.Get("ContentType"))
Output: ContentType is application/json
func AsContentType ¶
func AsContentType(contentType string) PrepareDecorator
AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value is the passed contentType.
func AsDelete ¶
func AsDelete() PrepareDecorator
AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE.
func AsFormURLEncoded ¶
func AsFormURLEncoded() PrepareDecorator
AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is "application/x-www-form-urlencoded".
func AsGet ¶
func AsGet() PrepareDecorator
AsGet returns a PrepareDecorator that sets the HTTP method to GET.
func AsHead ¶
func AsHead() PrepareDecorator
AsHead returns a PrepareDecorator that sets the HTTP method to HEAD.
func AsJSON ¶
func AsJSON() PrepareDecorator
AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is "application/json".
func AsOptions ¶
func AsOptions() PrepareDecorator
AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS.
func AsPatch ¶
func AsPatch() PrepareDecorator
AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH.
func AsPost ¶
func AsPost() PrepareDecorator
AsPost returns a PrepareDecorator that sets the HTTP method to POST.
func AsPut ¶
func AsPut() PrepareDecorator
AsPut returns a PrepareDecorator that sets the HTTP method to PUT.
func WithBaseURL ¶
func WithBaseURL(baseURL string) PrepareDecorator
WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed from the supplied baseUrl.
Example ¶
Create a request for a supplied base URL and path
r, err := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/a/b/c/")) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a/b/c/
func WithBearerAuthorization ¶
func WithBearerAuthorization(token string) PrepareDecorator
WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value is "Bearer " followed by the supplied token.
func WithBool ¶
func WithBool(v bool) PrepareDecorator
WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request and sets the Content-Length header.
func WithEscapedPathParameters ¶
func WithEscapedPathParameters(pathParameters map[string]interface{}) PrepareDecorator
WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The values will be escaped (aka URL encoded) before insertion into the path.
Example ¶
Create a request from a path with escaped parameters
params := map[string]interface{}{ "param1": "a b c", "param2": "d e f", } r, err := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/"), WithPath("/{param1}/b/{param2}/"), WithEscapedPathParameters(params)) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a+b+c/b/d+e+f/
func WithFloat32 ¶
func WithFloat32(v float32) PrepareDecorator
WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the request and sets the Content-Length header.
func WithFloat64 ¶
func WithFloat64(v float64) PrepareDecorator
WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the request and sets the Content-Length header.
func WithFormData ¶
func WithFormData(v url.Values) PrepareDecorator
WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the http.Request body.
Example ¶
Create a request whose Body is the JSON encoding of a structure
v := url.Values{} v.Add("name", "Rob Pike") v.Add("age", "42") r, err := Prepare(&http.Request{}, WithFormData(v)) if err != nil { fmt.Printf("ERROR: %v\n", err) } b, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Printf("Request Body contains %s\n", string(b)) }
Output: Request Body contains age=42&name=Rob+Pike
func WithHeader ¶
func WithHeader(header string, value string) PrepareDecorator
WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before adding the header.
Example ¶
Create a request with a custom HTTP header
r, err := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/a/b/c/"), WithHeader("x-foo", "bar")) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Printf("Header %s=%s\n", "x-foo", r.Header.Get("x-foo")) }
Output: Header x-foo=bar
func WithInt32 ¶
func WithInt32(v int32) PrepareDecorator
WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request and sets the Content-Length header.
func WithInt64 ¶
func WithInt64(v int64) PrepareDecorator
WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request and sets the Content-Length header.
func WithJSON ¶
func WithJSON(v interface{}) PrepareDecorator
WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the request and sets the Content-Length header.
Example ¶
Create a request whose Body is the JSON encoding of a structure
t := mocks.T{Name: "Rob Pike", Age: 42} r, err := Prepare(&http.Request{}, WithJSON(&t)) if err != nil { fmt.Printf("ERROR: %v\n", err) } b, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Printf("Request Body contains %s\n", string(b)) }
Output: Request Body contains {"name":"Rob Pike","age":42}
func WithMethod ¶
func WithMethod(method string) PrepareDecorator
WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The decorator does not validate that the passed method string is a known HTTP method.
func WithNothing ¶
func WithNothing() PrepareDecorator
WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed http.Request.
func WithPath ¶
func WithPath(path string) PrepareDecorator
WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path is absolute (that is, it begins with a "/"), it replaces the existing path.
func WithPathParameters ¶
func WithPathParameters(pathParameters map[string]interface{}) PrepareDecorator
WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map.
Example ¶
Create a request from a path with parameters
params := map[string]interface{}{ "param1": "a", "param2": "c", } r, err := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/"), WithPath("/{param1}/b/{param2}/"), WithPathParameters(params)) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a/b/c/
func WithQueryParameters ¶
func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator
WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters given in the supplied map (i.e., key=value).
Example ¶
Create a request with query parameters
params := map[string]interface{}{ "q1": "value1", "q2": "value2", } r, err := Prepare(&http.Request{}, WithBaseURL("https://microsoft.com/"), WithPath("/a/b/c/"), WithQueryParameters(params)) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a/b/c/?q1=value1&q2=value2
func WithString ¶
func WithString(v string) PrepareDecorator
WithString returns a PrepareDecorator that encodes the passed string into the body of the request and sets the Content-Length header.
func WithUserAgent ¶
func WithUserAgent(ua string) PrepareDecorator
WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the passed string.
type Preparer ¶
Preparer is the interface that wraps the Prepare method.
Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations must ensure to not share or hold per-invocation state since Preparers may be shared and re-used.
func CreatePreparer ¶
func CreatePreparer(decorators ...PrepareDecorator) Preparer
CreatePreparer creates, decorates, and returns a Preparer. Without decorators, the returned Preparer returns the passed http.Request unmodified. Preparers are safe to share and re-use.
Example ¶
Create a sequence of three Preparers that build up the URL path.
p := CreatePreparer( WithBaseURL("https://microsoft.com/"), WithPath("a"), WithPath("b"), WithPath("c")) r, err := p.Prepare(&http.Request{}) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a/b/c
Example (Chain) ¶
Create and chain separate Preparers
params := map[string]interface{}{ "param1": "a", "param2": "c", } p := CreatePreparer(WithBaseURL("https://microsoft.com/"), WithPath("/{param1}/b/{param2}/")) p = DecoratePreparer(p, WithPathParameters(params)) r, err := p.Prepare(&http.Request{}) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a/b/c/
Example (Multiple) ¶
Create and apply separate Preparers
params := map[string]interface{}{ "param1": "a", "param2": "c", } p1 := CreatePreparer(WithBaseURL("https://microsoft.com/"), WithPath("/{param1}/b/{param2}/")) p2 := CreatePreparer(WithPathParameters(params)) r, err := p1.Prepare(&http.Request{}) if err != nil { fmt.Printf("ERROR: %v\n", err) } r, err = p2.Prepare(r) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println(r.URL) }
Output: https://microsoft.com/a/b/c/
func DecoratePreparer ¶
func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer
DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it applies to the Preparer. Decorators are applied in the order received, but their affect upon the request depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a post-decorator (pass the http.Request along and alter it on return).
type PreparerFunc ¶
PreparerFunc is a method that implements the Preparer interface.
type RespondDecorator ¶
RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to the http.Response and pass it along or, first, pass the http.Response along then react.
func ByClosing ¶
func ByClosing() RespondDecorator
ByClosing returns a RespondDecorator that first invokes the passed Responder after which it closes the response body. Since the passed Responder is invoked prior to closing the response body, the decorator may occur anywhere within the set.
func ByClosingIfError ¶
func ByClosingIfError() RespondDecorator
ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which it closes the response if the passed Responder returns an error and the response body exists.
func ByCopying ¶
func ByCopying(b *bytes.Buffer) RespondDecorator
ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as the Body is read.
func ByIgnoring ¶
func ByIgnoring() RespondDecorator
ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined to the next RespondDecorator.
func ByUnmarshallingJSON ¶
func ByUnmarshallingJSON(v interface{}) RespondDecorator
ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the response Body into the value pointed to by v.
Example ¶
c := ` { "name" : "Rob Pike", "age" : 42 } ` type V struct { Name string `json:"name"` Age int `json:"age"` } v := &V{} Respond(mocks.NewResponseWithContent(c), ByUnmarshallingJSON(v), ByClosing()) fmt.Printf("%s is %d years old\n", v.Name, v.Age)
Output: Rob Pike is 42 years old
func ByUnmarshallingXML ¶
func ByUnmarshallingXML(v interface{}) RespondDecorator
ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the response Body into the value pointed to by v.
Example ¶
c := `<?xml version="1.0" encoding="UTF-8"?> <Person> <Name>Rob Pike</Name> <Age>42</Age> </Person>` type V struct { Name string `xml:"Name"` Age int `xml:"Age"` } v := &V{} Respond(mocks.NewResponseWithContent(c), ByUnmarshallingXML(v), ByClosing()) fmt.Printf("%s is %d years old\n", v.Name, v.Age)
Output: Rob Pike is 42 years old
func WithErrorUnlessOK ¶
func WithErrorUnlessOK() RespondDecorator
WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is anything other than HTTP 200.
Example ¶
r := mocks.NewResponse() r.Request = mocks.NewRequest() // Respond and leave the response body open (for a subsequent responder to close) err := Respond(r, WithErrorUnlessOK(), ByClosingIfError()) if err == nil { fmt.Printf("%s of %s returned HTTP 200", r.Request.Method, r.Request.URL) // Complete handling the response and close the body Respond(r, ByClosing()) }
Output: GET of https://microsoft.com/a/b/c/ returned HTTP 200
func WithErrorUnlessStatusCode ¶
func WithErrorUnlessStatusCode(codes ...int) RespondDecorator
WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response StatusCode is among the set passed. Since these are artificial errors, the response body may still require closing.
type Responder ¶
Responder is the interface that wraps the Respond method.
Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold state since Responders may be shared and re-used.
func CreateResponder ¶
func CreateResponder(decorators ...RespondDecorator) Responder
CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned Responder returns the passed http.Response unmodified. Responders may or may not be safe to share and re-used: It depends on the applied decorators. For example, a standard decorator that closes the response body is fine to share whereas a decorator that reads the body into a passed struct is not.
To prevent memory leaks, ensure that at least one Responder closes the response body.
func DecorateResponder ¶
func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder
DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it applies to the Responder. Decorators are applied in the order received, but their affect upon the request depends on whether they are a pre-decorator (react to the http.Response and then pass it along) or a post-decorator (pass the http.Response along and then react).
type ResponderFunc ¶
ResponderFunc is a method that implements the Responder interface.
type Response ¶
Response serves as the base for all responses from generated clients. It provides access to the last http.Response.
type SendDecorator ¶
SendDecorator takes and possibily decorates, by wrapping, a Sender. Decorators may affect the http.Request and pass it along or, first, pass the http.Request along then react to the http.Response result.
func AfterDelay ¶
func AfterDelay(d time.Duration) SendDecorator
AfterDelay returns a SendDecorator that delays for the passed time.Duration before invoking the Sender. The delay may be terminated by closing the optional channel on the http.Request. If canceled, no further Senders are invoked.
func AsIs ¶
func AsIs() SendDecorator
AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request.
func DoCloseIfError ¶
func DoCloseIfError() SendDecorator
DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which it closes the response if the passed Sender returns an error and the response body exists.
func DoErrorIfStatusCode ¶
func DoErrorIfStatusCode(codes ...int) SendDecorator
DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is among the set passed. Since these are artificial errors, the response body may still require closing.
Example ¶
client := mocks.NewSender() client.AppendAndRepeatResponse(mocks.NewResponseWithStatus("204 NoContent", http.StatusNoContent), 10) // Chain decorators to retry the request, up to five times, if the status code is 204 r, _ := SendWithSender(client, mocks.NewRequest(), DoErrorIfStatusCode(http.StatusNoContent), DoCloseIfError(), DoRetryForAttempts(5, time.Duration(0))) Respond(r, ByClosing()) fmt.Printf("Retry stopped after %d attempts with code %s", client.Attempts(), r.Status)
Output: Retry stopped after 5 attempts with code 204 NoContent
func DoErrorUnlessStatusCode ¶
func DoErrorUnlessStatusCode(codes ...int) SendDecorator
DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response StatusCode is among the set passed. Since these are artificial errors, the response body may still require closing.
func DoPollForStatusCodes ¶
DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the passed status codes. It expects the http.Response to contain a Location header providing the URL at which to poll (using GET) and will poll until the time passed is equal to or greater than the supplied duration. It will delay between requests for the duration specified in the RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by closing the optional channel on the http.Request.
func DoRetryForAttempts ¶
func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator
DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified number of attempts, exponentially backing off between requests using the supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on the http.Request.
Example ¶
client := mocks.NewSender() client.SetAndRepeatError(fmt.Errorf("Faux Error"), 10) // Retry with backoff -- ensure returned Bodies are closed r, _ := SendWithSender(client, mocks.NewRequest(), DoCloseIfError(), DoRetryForAttempts(5, time.Duration(0))) Respond(r, ByClosing()) fmt.Printf("Retry stopped after %d attempts", client.Attempts())
Output: Retry stopped after 5 attempts
func DoRetryForDuration ¶
func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator
DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal to or greater than the specified duration, exponentially backing off between requests using the supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on the http.Request.
func WithLogging ¶
func WithLogging(logger *log.Logger) SendDecorator
WithLogging returns a SendDecorator that implements simple before and after logging of the request.
type Sender ¶
Sender is the interface that wraps the Do method to send HTTP requests.
The standard http.Client conforms to this interface.
func CreateSender ¶
func CreateSender(decorators ...SendDecorator) Sender
CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
func DecorateSender ¶
func DecorateSender(s Sender, decorators ...SendDecorator) Sender
DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to the Sender. Decorators are applied in the order received, but their affect upon the request depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a post-decorator (pass the http.Request along and react to the results in http.Response).
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package azure provides Azure-specific implementations used with AutoRest.
|
Package azure provides Azure-specific implementations used with AutoRest. |
Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) defined date formats: Date and DateTime.
|
Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) defined date formats: Date and DateTime. |
Package mocks provides mocks and helpers used in testing.
|
Package mocks provides mocks and helpers used in testing. |
Package to provides helpers to ease working with pointer values of marshalled structures.
|
Package to provides helpers to ease working with pointer values of marshalled structures. |