Documentation ¶
Index ¶
- Constants
- Variables
- func NewContext(ctx context.Context, v *Request) context.Context
- func ValuesOf(v interface{}) (url.Values, error)
- type DebugOptions
- type Extension
- func (e Extension) Decode(ctx context.Context, body []byte, out interface{}) error
- func (e Extension) Encode(ctx context.Context, body interface{}) ([]byte, error)
- func (e Extension) HandleOption(r *Request, o interface{}) (bool, error)
- func (e Extension) OnRequest(r *http.Request) error
- func (e Extension) OnResponse(r *http.Response) error
- func (e Extension) RoundTrip(r *http.Request) (*http.Response, error)
- func (e *Extension) With(h ...Hook)
- type Hook
- type Request
- func (r Request) Do() (*http.Response, error)
- func (r Request) Fetch(out ...interface{}) error
- func (r Request) FetchBytes() ([]byte, *http.Response, error)
- func (r Request) FetchString() (string, *http.Response, error)
- func (r Request) NewRequest() (*http.Request, error)
- func (r *Request) Reconcile() error
- func (r Request) With(o Request) Request
- func (r Request) WithHook(h ...Hook) Request
Examples ¶
Constants ¶
View Source
const RequestContextKey = contextKey("Request")
RequestContextKey for Request instance
Variables ¶
View Source
var FormEncode = Hook{ Name: "FormEncode", OnRequest: func(r *http.Request) error { if r.Header.Get("Content-Type") == "" { r.Header.Set("Content-Type", "application/x-www-form-urlencoded") } return nil }, Encode: func(ctx context.Context, body interface{}) ([]byte, error) { v, err := ValuesOf(body) if err != nil { return nil, err } return []byte(v.Encode()), nil }, }
FormEncode encode use ValuesOf
View Source
var JSONDecode = Hook{ Name: "JsonDecode", Decode: func(ctx context.Context, body []byte, out interface{}) error { return json.Unmarshal(body, out) }, }
JSONDecode decode use json.Unmarshal
View Source
var JSONEncode = Hook{ Name: "JsonEncode", OnRequest: func(r *http.Request) error { if r.Header.Get("Content-Type") == "" { r.Header.Set("Content-Type", "application/json;charset=UTF-8") } return nil }, Encode: func(ctx context.Context, body interface{}) ([]byte, error) { return json.Marshal(body) }, }
JSONEncode encode use json.Marshal, add Content-Type
View Source
var MultipartFormEncode = Hook{ Name: "MultipartFormEncode", OnRequest: func(r *http.Request) (err error) { if r.Body == nil { return errors.New("MultipartFormEncode need file body") } h := multipart.FileHeader{} switch f := r.Body.(type) { case fs.File: info, err := f.Stat() if err != nil { return err } h.Filename = info.Name() h.Size = info.Size() default: return errors.Errorf("unsupported file type: %T", r.Body) } r.GetBody = func() (io.ReadCloser, error) { b := &bytes.Buffer{} return io.NopCloser(b), nil } return }, }
Functions ¶
func NewContext ¶
NewContext with Request
Types ¶
type DebugOptions ¶
type DebugOptions struct { Disable bool // Disable turn off debug Body bool // Body enable dump http request and response's body Out io.Writer // Out debug output, default stderr ErrorOnly bool // ErrorOnly enable dump error only IsError func(r *http.Response) bool // IsError check if response is error, default is http.StatusOK < 400 }
DebugOptions options for DebugHook
type Extension ¶
type Extension struct {
Hooks []Hook
}
Extension of Request
func (Extension) HandleOption ¶
HandleOption process unknown options
func (Extension) OnResponse ¶
OnResponse process response
type Hook ¶
type Hook struct { Name string Order int OnRequest func(r *http.Request) error OnResponse func(r *http.Response) error HandleRequest func(next http.RoundTripper) http.RoundTripper HandleOption func(r *Request, o interface{}) (bool, error) Encode func(ctx context.Context, body interface{}) ([]byte, error) Decode func(ctx context.Context, body []byte, out interface{}) error }
Hook phases for Extension
func UseRoundTripper ¶
func UseRoundTripper(rt http.RoundTripper) Hook
UseRoundTripper use customized http.RoundTripper for Request
type Request ¶
type Request struct { Method string BaseURL string URL string Query interface{} RawQuery string RawBody []byte GetBody func() (io.ReadCloser, error) Body interface{} Header http.Header Context context.Context Values url.Values // Extra options for customized process - non string option use Context LastError error // Options support signatures // Request // func(*Request) // func(*Request) error // Hook // nil Options []interface{} Extension Extension }
Request is declarative HTTP client instance
Example ¶
// reusable client client := req.Request{ BaseURL: "https://httpbin.org", Options: []interface{}{req.JSONEncode, req.JSONDecode}, } // dump request and response with body client = client.WithHook(req.DebugHook(&req.DebugOptions{Body: true})) // send request with declarative override var out PostResponse var r *http.Response err := client.With(req.Request{ Method: http.MethodPost, URL: "/post", Body: HelloRequest{ Name: "go-req", }, }).Fetch(&out, &r) if err != nil { panic(err) } // print go-req fmt.Println(out.JSON.Name) // print 200 fmt.Println(r.StatusCode) // override Options use form encode err = client.With(req.Request{ Method: http.MethodPost, URL: "/post", Body: HelloRequest{ Name: "go-req", }, Options: []interface{}{req.FormEncode}, }).Fetch(&out) if err != nil { panic(err) } // print go-req fmt.Println(out.Form.Name)
Output:
func FromContext ¶
FromContext get Request from context.Context
func (Request) FetchBytes ¶
FetchBytes return bytes
func (Request) FetchString ¶
FetchString return string
func (Request) NewRequest ¶
NewRequest create http.Request
Click to show internal directories.
Click to hide internal directories.