Documentation ¶
Overview ¶
Package httpm provides functions to produce and consume http messages.
It's main goal is to reduce the boilerplate due to: * writing request and reading response on client side * reading request and writing response on server side The ComposeXXX functions return the possible error that occures during composition, leaving a very clean describtion of what to do when composing or consuming a message. // Classic way ... raw, err := ioutil.ReadAll(r.Body) if err != nil { ... } if err := json.Unmarshal(raw, &target); err != nil { ... } if err := check(target); err != nil { ... } if err := parseParams(r.URL, ¶ms); err != nil { ... } // With httpm ... parse := httpm.ComposeRequest( httpm.ReadRequestBody(httpm.DecodeAndCheck(json.Unmarshal, check), httpm.ReadRequestParams(parseParams), ) r, err := parse(r) if err != nil { ... }
Index ¶
- func DecodeText(raw []byte, v interface{}) error
- func EncodeText(v interface{}) ([]byte, error)
- func ExtendStatusCoder(next http.Handler) http.Handler
- func NewSender(client Doer) func(RequestFn, ResponseFn) error
- func ReadRequestBody(d Decoder) func(into interface{}) RequestFn
- func ReadRequestParams(fn ParamParser) func(interface{}) RequestFn
- func ReadResponseBody(d Decoder) func(into interface{}) ResponseFn
- func Send(in RequestFn, out ResponseFn) error
- func WriteRequestBody(e Encoder) func(input interface{}) RequestFn
- func WriteResponseWriterBody(e Encoder) func(interface{}) ResponseWriterFn
- type Caller
- type CallerFunc
- type Checker
- type ClientMiddleware
- type Decoder
- type Doer
- type Encoder
- type ParamParser
- type RequestFn
- type ResponseFn
- type ResponseWriterFn
- type StatusCoder
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DecodeText ¶
DecodeText decodes the raw data into the input. Input must be of type *[]byte, *string, or encoding.TextUnmarshaler
func EncodeText ¶
EncodeText encodes string, []byte and text.Marshaller implementations.
func ExtendStatusCoder ¶
ExtendStatusCoder is a middleware that extends the current http.ResponseWriter into a StatusCoder.
func NewSender ¶
func NewSender(client Doer) func(RequestFn, ResponseFn) error
NewSender returns a function that sends a request and handling its response with the given doer. See Send for details.
func ReadRequestBody ¶
ReadRequestBody decodes the request body.
func ReadRequestParams ¶
func ReadRequestParams(fn ParamParser) func(interface{}) RequestFn
ReadRequestParams decodes the request parameters.
func ReadResponseBody ¶
func ReadResponseBody(d Decoder) func(into interface{}) ResponseFn
ReadResponseBody decodes the body.
func Send ¶
func Send(in RequestFn, out ResponseFn) error
Send a request and handles its response with the http.DefaultClient.
If in is nil, Send returns an error. If out is nil, the response is not handled. This can be useful for fire & forget usages.
func WriteRequestBody ¶
WriteRequestBody encodes and writes the given input in the body.
func WriteResponseWriterBody ¶
func WriteResponseWriterBody(e Encoder) func(interface{}) ResponseWriterFn
WriteResponseWriterBody encodes and writes the given input in the body.
Types ¶
type Caller ¶ added in v0.3.0
type Caller interface {
Call(ctx context.Context, method, url string, h http.Header, in, out interface{}) error
}
Caller is the client side interface responsible for doing HTTP calls.
func Chain ¶ added in v0.3.0
func Chain(caller Caller, ms ...ClientMiddleware) Caller
Chain the middlewares around the caller. Chain(a, b, c).Call(ctx, method, url, h, in, out) is the equivalent to (c(b(a(ctx, method, url, h, in, out)))
type CallerFunc ¶ added in v0.3.0
type CallerFunc func(ctx context.Context, method, url string, h http.Header, in, out interface{}) error
CallerFunc is a function that can be used as a caller.
type Checker ¶
type Checker = func(interface{}) error
Checker is a func that checks the validity of an input.
type ClientMiddleware ¶ added in v0.3.0
ClientMiddleware is a function that chains caller.
type Decoder ¶
Decoder describes a type capable of decoding a []byte.
func DecodeAndCheck ¶
DecodeAndCheck the input.
type Doer ¶
Doer describes a type capable of sending Requests and returning responses. *http.Client is the cannonical implementation of a Doer.
type ParamParser ¶
ParamParser designates a function capable of parsing URL params.
type RequestFn ¶
RequestFn describes a function that can be member of a chainable Request handling.
func ComposeRequest ¶
ComposeRequest composes a list of RequestFn into one. ComposeRequest(foo, bar) is functionnally equivalent to bar(foo(r))
Example (Client) ¶
package main import ( "log" "net/http" "github.com/moxar/middleman/httpm" ) func main() { var encode httpm.Encoder // json.Marshal NewRequest := func(path, url string, input interface{}) (*http.Request, error) { return httpm.ComposeRequest( httpm.NewRequest(path, url), httpm.WriteRequestBody(encode)(input), )(nil) } type Hero struct { Name string Universe string } // Compose request. batman := Hero{Name: "Batman", Universe: "DC"} r, err := NewRequest("POST", "https://api.superheroes.com/heroes", batman) if err != nil { log.Println(err) } // use r _ = r }
Output:
Example (Server) ¶
package main import ( "net/http" "github.com/moxar/middleman/httpm" ) func main() { var parseParams httpm.ParamParser // gorilla/schema.NewDecoder().Decode var check httpm.Checker // asaskevich/govalidator.ValidateStruct var decode httpm.Decoder // json.Unmarshal // parseRequest parses the request params (?foo=bar) and body. parseRequest := func(r *http.Request, body, params interface{}) error { _, err := httpm.ComposeRequest( httpm.ReadRequestBody(httpm.DecodeAndCheck(decode, check))(body), httpm.ReadRequestParams(parseParams)(params), )(r) return err } type Hero struct { Name string Universe string } type Params struct { FastInsert bool } // HTTP Handler... handle := func(w http.ResponseWriter, r *http.Request) { var hero Hero var params Params if err := parseRequest(r, &hero, ¶ms); err != nil { // ... } // use hero and params values } _ = handle }
Output:
func NewRequest ¶
NewRequest prepares a http request with the standard http.NewRequest method.
func SetRequestContext ¶ added in v0.1.0
SetRequestContext adds the context to the request.
func SetRequestHeader ¶ added in v0.2.0
SetRequestHeader sets the header of the request.
type ResponseFn ¶
ResponseFn describes a function that can be member of a chainable Response handling.
func ComposeResponse ¶
func ComposeResponse(fns ...ResponseFn) ResponseFn
ComposeResponse composes a list of ResponseFns into one. ComposeResponse(foo, bar) is functionnally equivalent to bar(foo(w))
Example (Client) ¶
package main import ( "errors" "fmt" "io/ioutil" "log" "net/http" "strings" "github.com/moxar/middleman/httpm" ) func main() { FailOver400 := func(s int) error { if s <= 400 { return nil } return errors.New(http.StatusText(s)) } // Compose response. ParseResponse := func(r *http.Response, status *int, payload *string) error { _, err := httpm.ComposeResponse( httpm.ReadResponseStatus(status), httpm.ReturnErrorFromResponseStatus(FailOver400), httpm.ReadResponseBody(httpm.DecodeText)(payload), )(r) return err } r := &http.Response{ Body: ioutil.NopCloser(strings.NewReader(`some payload`)), StatusCode: 305, } var out string var status int err := ParseResponse(r, &status, &out) if err != nil { log.Println(err) } fmt.Println(out) fmt.Println(status) // use r _ = r }
Output: some payload 305
func ReadResponseStatus ¶
func ReadResponseStatus(status *int) ResponseFn
ReadResponseStatus into status.
func ReturnErrorFromResponseStatus ¶
func ReturnErrorFromResponseStatus(f func(status int) error) ResponseFn
ReturnErrorFromResponseStatus returns an error depending on the response status.
type ResponseWriterFn ¶
type ResponseWriterFn = func(w http.ResponseWriter) http.ResponseWriter
ResponseWriterFn describes a function that can be member of a chainable ResponseWriter handling.
func ComposeResponseWriter ¶
func ComposeResponseWriter(fn ...ResponseWriterFn) ResponseWriterFn
ComposeResponseWriter composes a list of ResponseWriterFn into one. ComposeResponseWriter(foo, bar) is functionnally equivalent to bar(foo(r))
Example (Server) ¶
package main import ( "net/http" "github.com/moxar/middleman/httpm" ) func main() { writeResponse := func(w http.ResponseWriter, payload interface{}, status int) { httpm.ComposeResponseWriter( httpm.WriteResponseWriterStatus(status), httpm.WriteResponseWriterBody(httpm.EncodeText)(payload), )(w) } var w http.ResponseWriter writeResponse(w, "some payload", http.StatusNoContent) }
Output:
func WriteResponseWriterStatus ¶
func WriteResponseWriterStatus(status int) ResponseWriterFn
WriteResponseWriterStatus writes the input status code as header.
type StatusCoder ¶
type StatusCoder interface {
StatusCode() int
}
StatusCoder returns the StatusCode.