diff --git a/errors.go b/errors.go index 3dcafd0..ce5e9b9 100644 --- a/errors.go +++ b/errors.go @@ -1,17 +1,20 @@ package impart import ( "net/http" ) +// HTTPError holds an HTTP status code and an error message. type HTTPError struct { Status int Message string } +// Error displays the HTTPError's error message and satisfies the error +// interface. func (h HTTPError) Error() string { if h.Message == "" { return http.StatusText(h.Status) } return h.Message } diff --git a/impart.go b/impart.go new file mode 100644 index 0000000..a2e17d1 --- /dev/null +++ b/impart.go @@ -0,0 +1,4 @@ +// Package impart provides a simple interface for a JSON-based API. It is +// designed for passing errors around a web application, sending back a status +// code and error message if needed, or a status code and some data on success. +package impart diff --git a/response.go b/response.go index b33b9c8..2b0dcbc 100644 --- a/response.go +++ b/response.go @@ -1,53 +1,61 @@ package impart import ( "encoding/json" "net/http" "strconv" ) type ( // Envelope contains metadata and optional data for a response object. + // Responses will always contain a status code and either: + // - response Data on a 2xx response, or + // - an ErrorMessage on non-2xx responses + // + // ErrorType is not currently used. Envelope struct { Code int `json:"code"` ErrorType string `json:"error_type,omitempty"` ErrorMessage string `json:"error_msg,omitempty"` Data interface{} `json:"data,omitempty"` } ) func writeBody(w http.ResponseWriter, body []byte, status int, contentType string) error { w.Header().Set("Content-Type", contentType+"; charset=UTF-8") w.Header().Set("Content-Length", strconv.Itoa(len(body))) w.WriteHeader(status) _, err := w.Write(body) return err } func renderJSON(w http.ResponseWriter, value interface{}, status int) error { body, err := json.Marshal(value) if err != nil { return err } return writeBody(w, body, status, "application/json") } func renderString(w http.ResponseWriter, status int, msg string) error { return writeBody(w, []byte(msg), status, "text/plain") } +// WriteError writes the successful data and metadata to the ResponseWriter as +// JSON. func WriteSuccess(w http.ResponseWriter, data interface{}, status int) error { env := &Envelope{ Code: status, Data: data, } return renderJSON(w, env, status) } +// WriteError writes the error to the ResponseWriter as JSON. func WriteError(w http.ResponseWriter, e HTTPError) error { env := &Envelope{ Code: e.Status, ErrorMessage: e.Message, } return renderJSON(w, env, e.Status) }