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