package internal import ( "encoding/json" "fmt" "log" "net/http" ) type RestResponse struct { Status int Headers http.Header Payload struct { Success bool `json:"success"` Payload interface{} `json:"payload"` } } func BasicResponse(success bool, model interface{}) *RestResponse { return &RestResponse{ Status: http.StatusOK, Payload: struct { Success bool "json:\"success\"" Payload interface{} "json:\"payload\"" }{Success: success, Payload: model}, } } func ErrorResponse(status int, err error) *RestResponse { return &RestResponse{ Status: status, Payload: struct { Success bool "json:\"success\"" Payload interface{} "json:\"payload\"" }{ Success: false, Payload: err.Error(), }, } } func (rr *RestResponse) Write(w http.ResponseWriter) error { if rr.Status != 0 && rr.Status != 200 { w.WriteHeader(rr.Status) } for k, v := range rr.Headers { for _, ve := range v { w.Header().Add(k, ve) } } e := json.NewEncoder(w) e.SetIndent("\n", "\t") if err := e.Encode(rr.Payload); err != nil { return fmt.Errorf("could not serialize struct for http response: %w", err) } return nil } type RestHandler func(request *http.Request) (*RestResponse, error) func (rh RestHandler) ToHF() http.HandlerFunc { return func(rw http.ResponseWriter, r *http.Request) { // rid := r.Context().Value(middleware.RequestIDKey) // rw.Header().Set(middleware.RequestIDHeader, rid.(string)) rh.ServeHTTP(rw, r) } } func (rh RestHandler) Error(e error) *RestResponse { return &RestResponse{ Status: http.StatusInternalServerError, Payload: struct { Success bool `json:"success"` Payload interface{} `json:"payload"` }{ Success: false, Payload: e.Error(), }, } } func (r RestHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { response, err := r(req) if err != nil { response = r.Error(err) } if err := response.Write(w); err != nil { log.Printf("Error occurred handling rest response: %v", err) } }