Documentation
¶
Overview ¶
Package conversation deals with requests and responses while having an HTTP conversation. It provides convenience functions for dealing with common REST conversations.
Index ¶
- Constants
- Variables
- func Reply(w http.ResponseWriter, body interface{}) error
- func Respond(w http.ResponseWriter, code int) error
- func Success(r *http.Response) bool
- func Unmarshal(r io.Reader, in interface{}) error
- func Write(w http.ResponseWriter, code int, body []byte) error
- type Error
- type Request
Examples ¶
Constants ¶
const DefaultTimeout = time.Second * 10
DefaultTimeout used by clients if no client is defined on a Request.
Variables ¶
var ErrNilResponse = errors.New("nil response")
ErrNilResponse is returned if an attempted is made to unmarshal a nil response.
Functions ¶
func Reply ¶
func Reply(w http.ResponseWriter, body interface{}) error
Reply to the conversation with an HTTP OK and the given body. Bodies that are not of type []byte or string will be marshalled into JSON. If the marshall failed a 500 error is sent and an error returned. Zero length bodies will simply result in the default 200 status text.
Example ¶
package main import ( "bytes" "fmt" "net/http/httptest" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { w := httptest.ResponseRecorder{Body: &bytes.Buffer{}} if err := conversation.Reply(&w, []byte("body")); err != nil { fmt.Println(err) } else { fmt.Println(w.Body.String()) } w = httptest.ResponseRecorder{Body: &bytes.Buffer{}} if err := conversation.Reply(&w, "body"); err != nil { fmt.Println(err) } else { fmt.Println(w.Body.String()) } w = httptest.ResponseRecorder{Body: &bytes.Buffer{}} payload := struct{ Data string }{Data: "body"} if err := conversation.Reply(&w, payload); err != nil { fmt.Println(err) } else { fmt.Println(w.Body.String()) } }
Output: body body {"Data":"body"}
func Respond ¶
func Respond(w http.ResponseWriter, code int) error
Respond using the default HTTP status text.
func Success ¶
Success returns true if the HTTP Response type contains a success code (200, 201, 202).
Example ¶
package main import ( "fmt" "net/http" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { fmt.Println(conversation.Success(&http.Response{StatusCode: 200})) fmt.Println(conversation.Success(&http.Response{StatusCode: 400})) fmt.Println(conversation.Success(nil)) }
Output: true false false
func Unmarshal ¶
Unmarshal a JSON request or response into the given interface. The interface should be a pointer.
Example ¶
package main import ( "bytes" "fmt" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { var body string err := conversation.Unmarshal(bytes.NewReader([]byte(`"body"`)), &body) if err != nil { fmt.Println(err) } fmt.Println(body) }
Output: body
func Write ¶
func Write(w http.ResponseWriter, code int, body []byte) error
Write an HTTP response, adding some extra headers along the way. If no body is set then the default HTTP status text for that code will be used.
Example ¶
package main import ( "bytes" "fmt" "net/http" "net/http/httptest" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { header := "X-Content-Type-Options" w := httptest.ResponseRecorder{Body: &bytes.Buffer{}} err := conversation.Write(&w, http.StatusOK, []byte("body")) if err != nil { fmt.Println(err) } fmt.Printf("%s: %s\n", header, w.Header().Get(header)) fmt.Printf("%d - %s\n", w.Code, w.Body.String()) }
Output: X-Content-Type-Options: nosniff 200 - body
Types ¶
type Error ¶ added in v0.3.0
type Error struct { // Channel can receive 0-n errors. Channel chan<- error }
Error allows handling of multiple errors during a conversation by passing the errors onto a channel to be handled asynchronously. This allows conversations to be completed even if an action during the conversation fails.
func (Error) Handle ¶ added in v0.3.0
Handle an error. If the errors is non-nil and a channel is registered with the handler then that error will be put onto the channel.
Example ¶
package main import ( "errors" "fmt" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { c := make(chan error) e := conversation.Error{Channel: c} go e.Handle(nil) go e.Handle(errors.New("error")) fmt.Println(<-c) }
Output: error
type Request ¶
type Request struct { // Username if Basic Auth is being used. Password must also be set. Username string // Password is Basic Auth is being used. Username must also be set. Password string // Headers to use on the request. If Basic Auth is being used then the // Authorisation header is set before the headers are applied. Headers map[string]string // Client used for the request. If no client is set then a default client // will be constructed. Client *http.Client }
Request allows for simple HTTP requests to be made to a URL. If a Username and Password is set then Basic Auth will be used. If no client is set then a default client is constructed using the DefaultTimeout.
func (Request) Get ¶
Get the response from the given url. Get is a convenience method around Make which uses MethodGet and a nil body.
Example ¶
package main import ( "fmt" "net/http" "net/http/httptest" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { server := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { _ = conversation.Respond(w, http.StatusOK) })) response, err := http.Get(server.URL) if err != nil { fmt.Println(err) } _ = response.Body.Close() fmt.Println(conversation.Success(response)) }
Output: true
func (Request) Make ¶
Make a request, using Basic Auth if Username and Password are set. A client will be constructed for the request is none is set.
Example ¶
package main import ( "fmt" "net/http" "net/http/httptest" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { var body string server := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { u, p, _ := r.BasicAuth() h := r.Header.Get("header") _ = conversation.Reply(w, "\""+h+u+p+"\"") })) response, err := conversation.Request{ Username: "u", Password: "p", Headers: map[string]string{"header": "h"}, }.Make(http.MethodGet, server.URL, nil) if err != nil { fmt.Println(err) } _ = conversation.Unmarshal(response.Body, &body) _ = response.Body.Close() fmt.Println(body) }
Output: hup
func (Request) Post ¶
Post the payload to the given url. The payload will be marshalled into JSON. Post is a convenience method around Make which uses MethodPost and the output of json.Marshal for the body.
Example ¶
package main import ( "fmt" "net/http" "net/http/httptest" "bitbucket.org/idomdavis/gohttp/conversation" ) func main() { var body string server := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { var reply string _ = conversation.Unmarshal(r.Body, &reply) _ = conversation.Reply(w, reply) })) response, err := conversation.Request{}.Post(server.URL, `"body"`) if err != nil { fmt.Println(err) } _ = conversation.Unmarshal(response.Body, &body) _ = response.Body.Close() fmt.Println(body) }
Output: body