2018-10-07 09:23:00 +00:00
|
|
|
package api
|
2018-06-01 08:51:51 +00:00
|
|
|
|
|
|
|
import (
|
2019-05-01 11:44:45 +00:00
|
|
|
"encoding/json"
|
|
|
|
"net/http"
|
2018-06-01 08:51:51 +00:00
|
|
|
)
|
|
|
|
|
2019-05-01 11:44:45 +00:00
|
|
|
// ResponseData defines format for response parameters to return
|
|
|
|
type ResponseData map[string]interface{}
|
|
|
|
|
|
|
|
// Response represents an API response to be sent
|
|
|
|
type Response struct {
|
|
|
|
Data ResponseData
|
2019-05-01 14:40:26 +00:00
|
|
|
Status int
|
2019-05-01 11:44:45 +00:00
|
|
|
Headers http.Header
|
2019-05-01 16:23:57 +00:00
|
|
|
err Error
|
2019-05-01 11:44:45 +00:00
|
|
|
}
|
|
|
|
|
2019-05-01 16:01:32 +00:00
|
|
|
// NewResponse creates an empty response. An optional error can be passed as its first argument.
|
|
|
|
func NewResponse(errors ...Error) *Response {
|
|
|
|
res := &Response{
|
2019-05-01 14:40:26 +00:00
|
|
|
Status: http.StatusOK,
|
|
|
|
Data: make(ResponseData),
|
2019-05-01 16:23:57 +00:00
|
|
|
err: ErrorFailure(),
|
2019-05-01 14:40:26 +00:00
|
|
|
Headers: make(http.Header),
|
2018-06-01 08:51:51 +00:00
|
|
|
}
|
2019-05-01 16:01:32 +00:00
|
|
|
|
|
|
|
// optional error
|
|
|
|
if len(errors) == 1 {
|
2019-05-01 16:23:57 +00:00
|
|
|
res.err = errors[0]
|
2019-05-01 16:01:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return res
|
2018-06-01 08:51:51 +00:00
|
|
|
}
|
|
|
|
|
2019-05-01 16:23:57 +00:00
|
|
|
// SetError sets the error from a base error with error arguments.
|
|
|
|
func (res *Response) SetError(baseError Error, arguments ...interface{}) {
|
2019-05-01 16:15:44 +00:00
|
|
|
if len(arguments) > 0 {
|
2019-05-01 16:49:44 +00:00
|
|
|
baseError.SetArguments(arguments[0], arguments[1:]...)
|
2019-05-01 16:15:44 +00:00
|
|
|
}
|
2019-05-01 16:23:57 +00:00
|
|
|
res.err = baseError
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error implements the error interface and dispatches to internal error.
|
|
|
|
func (res *Response) Error() string {
|
|
|
|
return res.err.Error()
|
2019-05-01 16:15:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-01 11:44:45 +00:00
|
|
|
// SetData adds/overrides a new response field
|
2019-05-01 16:15:44 +00:00
|
|
|
func (res *Response) SetData(name string, value interface{}) {
|
|
|
|
res.Data[name] = value
|
2018-06-01 08:51:51 +00:00
|
|
|
}
|
|
|
|
|
2019-05-01 11:44:45 +00:00
|
|
|
// GetData gets a response field
|
2019-05-01 16:15:44 +00:00
|
|
|
func (res *Response) GetData(name string) interface{} {
|
|
|
|
value, _ := res.Data[name]
|
2018-06-01 08:51:51 +00:00
|
|
|
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
2019-05-01 11:44:45 +00:00
|
|
|
// MarshalJSON implements the 'json.Marshaler' interface and is used
|
|
|
|
// to generate the JSON representation of the response
|
2019-05-01 16:15:44 +00:00
|
|
|
func (res *Response) MarshalJSON() ([]byte, error) {
|
2019-05-01 13:14:49 +00:00
|
|
|
fmt := make(map[string]interface{})
|
|
|
|
|
2019-05-01 16:15:44 +00:00
|
|
|
for k, v := range res.Data {
|
2019-05-01 13:14:49 +00:00
|
|
|
fmt[k] = v
|
|
|
|
}
|
|
|
|
|
2019-05-01 16:23:57 +00:00
|
|
|
fmt["error"] = res.err
|
2019-05-01 13:14:49 +00:00
|
|
|
|
|
|
|
return json.Marshal(fmt)
|
2018-06-01 08:51:51 +00:00
|
|
|
}
|
2019-05-01 16:01:32 +00:00
|
|
|
|
2019-05-02 05:48:34 +00:00
|
|
|
// ServeHTTP implements http.Handler and writes the API response.
|
|
|
|
func (res *Response) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
|
2019-05-01 16:15:44 +00:00
|
|
|
w.WriteHeader(res.Status)
|
2019-05-01 16:01:32 +00:00
|
|
|
|
2020-03-09 18:12:26 +00:00
|
|
|
encoded, err := json.Marshal(res)
|
2019-05-01 16:01:32 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-03-09 18:12:26 +00:00
|
|
|
w.Write(encoded)
|
2019-05-01 16:01:32 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|